React 18 Beta의 Automatic Batching 동작 분석
배경
프로젝트에 React 18 Beta를 적용하기 전에 주요 변경사항을 검토하던 중 Automatic Batching에 대해 테스트해봤다. 기존 React 17에서는 이벤트 핸들러 내부에서만 배칭이 동작했는데, 18에서는 범위가 확장된다고 한다.
기존 동작 (React 17)
function handleClick() {
setCount(c => c + 1); // 배칭 O
setFlag(f => !f); // 배칭 O (1번 렌더링)
}
function fetchData() {
fetch('/api/data').then(() => {
setCount(c => c + 1); // 배칭 X
setFlag(f => !f); // 배칭 X (2번 렌더링)
});
}
이벤트 핸들러 밖의 비동기 콜백에서는 각 setState마다 렌더링이 발생했다.
React 18 변경사항
function fetchData() {
fetch('/api/data').then(() => {
setCount(c => c + 1); // 자동 배칭
setFlag(f => !f); // 자동 배칭 (1번 렌더링)
});
}
setTimeout(() => {
setCount(c => c + 1);
setFlag(f => !f); // 이것도 배칭됨
}, 1000);
모든 상황에서 자동으로 배칭된다. 실제로 렌더 카운터를 달아서 측정해보니 Promise, setTimeout 모두 1번만 렌더링됐다.
배칭 해제가 필요한 경우
간혹 즉시 DOM 업데이트가 필요한 경우 flushSync를 사용할 수 있다.
import { flushSync } from 'react-dom';
function handleClick() {
flushSync(() => {
setCount(c => c + 1);
});
// 여기서 DOM이 업데이트된 상태
flushSync(() => {
setFlag(f => !f);
});
}
결론
대부분의 경우 성능 향상으로 이어질 것으로 보인다. 특히 비동기 데이터 페칭 후 여러 상태를 업데이트하는 패턴에서 효과가 클 것 같다. 다만 정식 릴리즈 전까지는 프로덕션 적용은 보류할 예정이다.