지금 마커 정보가 업데이트 될 때 마커 컴포넌트에서 전역 마커 인스턴스 배열 상태를 업데이트 하고 있다.
이 전역 마커 인스턴스 배열 상태를 구독중인 컴포넌트가 있다면, 해당 컴포넌트는 마커가 최신화 될 때마다 리렌더링이 발생해야 하는데 현재 업데이트가 한번에 일어나는 신기한 현상이 발생하고 있다.
리액트의 batch state update에 의해 이렇게 되는 것으로 추정중이지만, 확실히 어떤 이유에서 이러한 현상이 발생하는지 분석하지 못했다. (해결!)
이 문제를 해결하기 위해 useState로 동일한 동작을 수행했을 때에도 상태 변경이 일어날 때마다 리렌더링이 발생하는지 예시 코드를 작성해 확인해보았다.
예시 코드는 다음과 같다.
// Parent.tsx
function Parent() {
const [parentArray, setParentArray] = useState<number[]>([]);
console.log(parentArray);
return (
<ul>
{Array.from({ length: 3000 }).map((_, i) => {
return <Child key={i} value={i} setParentArray={setParentArray} />;
})}
</ul>
);
}
// Child.tsx
function Child({ value, setParentArray }: Props) {
useEffect(() => {
setParentArray((prevArray) => [...prevArray, value]);
}, []);
return <li>{value}</li>;
}
// BatchUpdate.tsx
function BatchUpdate() {
const [isClicked, setIsClicked] = useState(false);
const startBatchUpdate = () => {
setIsClicked(true);
};
return (
<Layout title="배치 업데이트 테스트">
<button onClick={startBatchUpdate}>배치업데이트 시작</button>
{isClicked && <Parent />}
</Layout>
);
}
위 예시 코드에서의 기대 동작은 다음과 같다.
하지만 결과는 다음과 같았다.
Parent 컴포넌트의 내부 상태 변화는 3000번 발생하지 않고 단 한번만 발생한다.