React 18 alpha의 Automatic Batching 동작 확인
배경
React 18 alpha working group이 공개되면서 새로운 기능들을 미리 테스트해볼 수 있게 되었다. 그 중 Automatic Batching이 가장 체감이 클 것 같아 실험해봤다.
기존 React 17까지는 이벤트 핸들러 내부에서만 setState가 배치 처리되었다. Promise나 setTimeout 내부에서는 각 setState마다 리렌더링이 발생했다.
기존 동작 (React 17)
function Counter() {
const [count, setCount] = useState(0);
const [flag, setFlag] = useState(false);
function handleClick() {
fetch('/api').then(() => {
setCount(c => c + 1); // 리렌더링
setFlag(f => !f); // 리렌더링
});
}
console.log('rendered');
return <div>...</div>;
}
위 코드에서 handleClick 실행 시 'rendered'가 2번 찍혔다.
React 18에서의 변화
React 18부터는 Promise, setTimeout, native event handler 등 모든 곳에서 자동으로 배치 처리된다.
// React 18
fetch('/api').then(() => {
setCount(c => c + 1);
setFlag(f => !f);
// 한 번만 리렌더링
});
실제로 alpha 버전으로 테스트해보니 'rendered'가 1번만 찍혔다.
flushSync로 강제 렌더링
배치를 원하지 않는 경우 flushSync를 사용할 수 있다.
import { flushSync } from 'react-dom';
flushSync(() => {
setCount(c => c + 1);
});
// DOM 업데이트 완료
flushSync(() => {
setFlag(f => !f);
});
소감
성능 최적화를 위해 신경 써야 했던 부분이 프레임워크 레벨에서 해결되는 건 좋은 방향이다. 다만 아직 alpha라 프로덕션 적용은 이르고, 라이브러리 호환성을 지켜봐야 할 것 같다.