지금 마커 정보가 업데이트 될 때 마커 컴포넌트에서 전역 마커 인스턴스 배열 상태를 업데이트 하고 있다.

이 전역 마커 인스턴스 배열 상태를 구독중인 컴포넌트가 있다면, 해당 컴포넌트는 마커가 최신화 될 때마다 리렌더링이 발생해야 하는데 현재 업데이트가 한번에 일어나는 신기한 현상이 발생하고 있다.

리액트의 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>
  );
}

위 예시 코드에서의 기대 동작은 다음과 같다.

하지만 결과는 다음과 같았다.

Untitled

Parent 컴포넌트의 내부 상태 변화는 3000번 발생하지 않고 단 한번만 발생한다.