React 학습 5일 차: 배칭(Batching)과 함수형 업데이트(Functional Updates)
상태 세터(state setter)를 여러 번 호출하면 렌더링이 여러 번 일어난다고 생각했습니다.
제 생각이 틀렸습니다.
React는 그보다 더 똑똑합니다. '자동 배칭(Automatic Batching)'이라는 프로세스를 사용하거든요.
매 업데이트마다 렌더링을 하는 대신, React는 업데이트를 하나로 묶습니다. 모든 업데이트를 모아서 단 한 번의 렌더링을 수행합니다. 이를 통해 성능을 절약합니다.
오늘 배운 내용은 다음과 같습니다.
The Batching Process 여러 상태 함수를 호출하면 React는 다음과 같은 흐름을 따릅니다:
- 여러 상태 업데이트가 발생합니다.
- React가 이를 하나로 묶습니다(batching).
- React가 한 번의 렌더링을 수행합니다.
- React가 UI에 변경 사항을 반영(commit)합니다.
The Problem with Standard Updates 저는 다음과 같은 코드를 작성해 보았습니다: setCount(count + 1); setCount(count + 1); setCount(count + 1);
카운트가 0에서 3이 될 것이라고 예상했지만, 0에서 1이 되었습니다.
이는 setCount(count + 1)이 "카운트를 증가시켜라"라는 뜻이 아니기 때문입니다. "카운트를 이 특정 값으로 설정하라"라는 뜻입니다.
만약 count가 0이라면, 모든 줄이 React에게 count를 1로 설정하라고 명령합니다. React는 이를 배칭하여 최종 명령이 count를 1로 설정하는 것임을 확인합니다.
The Solution: Functional Updates 이를 해결하려면 함수형 업데이트를 사용해야 합니다. 이는 업데이트 큐(update queue)에서 사용 가능한 최신 상태를 사용합니다.
올바른 방법: setCount((prev) => prev + 1);
이 패턴을 사용하면 React는 각 업데이트에 가장 최근의 값을 전달합니다.
- 첫 번째 업데이트: 0 + 1 = 1
- 두 번째 업데이트: 1 + 1 = 2
- 세 번째 업데이트: 2 + 1 = 3
이제 카운터가 실제로 3에 도달합니다.
A Common Mistake 예전에 이렇게 작성한 적이 있습니다: setCount((prev) => { prev + 1 });
카운터가 undefined가 되었습니다. 화살표 함수에서 중괄호({})를 사용할 때는 반드시 return 키워드를 사용해야 합니다. 대신 이렇게 사용하세요: setCount((prev) => prev + 1);
Key Takeaways:
- React는 속도 향상을 위해 여러 상태 업데이트를 배칭합니다.
- setState 호출이 항상 즉각적인 렌더링을 유발하는 것은 아닙니다.
- 일반적인 업데이트는 현재 렌더링 사이클의 값을 사용합니다.
- 함수형 업데이트는 업데이트 큐의 최신 상태를 사용합니다.
- React는 이러한 변경 사항을 관리하기 위해 내부적인 업데이트 큐(Update Queue)를 사용합니다.
