[React] React의 state변경 (Batching)

현수·2022년 4월 28일
0

면접준비

목록 보기
10/10

Batching

React의 state를 변경시키는 것은 useState이다. state가 변경되면 컴포넌트는 리렌더링되는데, 이 때 React는 이를 비동기로 동작시킨다.

function App() {
  const [count, setCount] = useState(0);const [flag, setFlag] = useState(false);

  function handleClick() {
    setCount((c) => c + 1); // 아직 리렌더링 하지 않는다
    setFlag((f) => !f); // 아직 리렌더링 하지 않는다
    // React는 이 함수가 끝나면 리렌더링을 한다.
  }

  return (
    <div>
      <button onClick={handleClick}>Next</button>
      <h1 style=>{count}</h1>
    </div>
  );
}

위의 컴포넌트에서 button을 클릭하게되면 두 번의 state변경이 있었기 때문에, 렌더링도 두 번 일어날 것 같지만 사실은 함수 내에 있는 업데이트 함수 두 개가 모두 실행된 후에 한 번의 리렌더링만 일어나게 된다. 이를 React의 batching(배칭, 일괄처리)라고 한다. batching은 불필요한 리렌더링을 줄여주기 때문에 성능에 크게 도움을 준다.

batching이 일어나는 상황

batching은 이벤트 핸들러(함수)내에서 또는 메서드 내에서 동작한다. 따라서 같은 함수 안에 있는 업데이트가 한 번에 리렌더링 되고, useEffect와 같은 메서드 내에서 있는 업데이트가 모여 한 번에 리렌더링 된다.

하지만 모든 상황에서 batching이 실행되는 것은 아니다. 함수가 비동기처리 방식으로 실행되는 경우, async/await, then/catch, setTimeout, fetch 등의 경우에는 일괄적으로 처리되지 않는다.

  function handleClick() {
    fetchSomething().then(() => {
      setCount((c) => c + 1); // 리렌더링을 발생시킨다.
      setFlag((f) => !f); // 리렌더링을 발생시킨다.
    });
  }

첫 번째 코드와 유사한 상황이지만 위의 경우 then을 통해 이벤트 핸들링이 완료된 후에 state를 업데이트가 이루어지기 때문에 batching은 이루어지지 않고, 두 번의 리렌더링을 발생시키게 된다.

강제로 batching 적용시키기

비동기 처리로 batching이 이뤄지지 않는 경우에도 강제로 적용시키는 방법이 있는데 바로 ReactDOM.unstable_batchedUpdates를 사용하는 것이다.

import ReactDOM from "react-dom";

  function handleClick() {
    fetchSomething().then(() => {
      ReactDOM.unstable_batchedUpdates(() => {
      	setCount((c) => c + 1); 
      	setFlag((f) => !f);
      }  
    });
  }

이렇게 위와 같이 작성하는 경우 batching을 강제로 적용시킬 수 있다.


Automatic Batching(자동 배칭)

자동 배칭은 React 18버전에서 부터 *createRoot를 통해 적용된 것으로, 모든 업데이트가 어디에 포함되어 있는가와 관계없이 자동으로 batching 처리되도록 변경된 것을 말한다.

ReactDOM.unstable_batchedUpdates를 사용하지 않고도 모든 경우에 batching을 자동으로 처리해주기 때문에 당장 없어진 것은 아니지만 추후 버전 업데이트에서 사라질 가능성이 높아보인다.

또한 batching을 적용하고 싶지 않은 경우에는 ReactDOM.flushSync()를 사용하여 배칭을 하지 않도록 막는 것도 가능하다.




Reference

* createRoot : React 18 업데이트(번역글)

profile
언젠간 되겠지!

0개의 댓글