📑
React18のAuto Batchingの確認
背景
Auto Batchingがどのように起こるか確認する。状態変更のたびにレンダリングしていたのが1回になるという言及しているものがあったが、これはもともと1回のはずである。非同期処理で行うと複数回起きてしまうはずである。認識が正しいか確認したい。
先に、まとめ
イベントハンドラで複数回状態変更したときにReactが複数回レンダリングするかどうかを確認した。
React17ではsetTimeoutなどで非同期にして状態変更をすると複数回レンダリングしてしまうが、React18では行われなくなっていることが確認できた。
バージョン | 変更タイミング | レンダリング回数 |
---|---|---|
React17 | 同期 | 1回だけ |
React17 | 非同期 | 複数回 |
React18 | 同期 | 1回だけ |
React18 | 非同期 | 1回だけ |
React18の非同期実行時に明示的にレンダリングを行いたい場合はflushSyncを使う。
補足として、StrictModeを使うとReactElementの作成が複数回起きてしまう点には注意。
確認方法
React18とReact17で確認できるコードを用意した。
内容はこんな感じ(JSXの部分は省略)
const handleClick = () => {
setA((a) => a + 1);
setB((b) => b + 2); // React17でも1度だけ。
};
// 別のボタンから呼び出す。setTimeoutを使っている。
const handleAsyncClick = () => {
setTimeout(() => {
setA((a) => a + 1); // React17だとここでレンダリングが発生してしまう
setB((b) => b + 2);
}, 0);
};
useEffect(() => {
console.log("effect");
});
console.log("render", { a, b });
React18での動作確認用
React17での動作確認用
React17と同じようにしたい場合は以下のようにする。
const handleFlushSyncClick = () => {
setTimeout(() => {
flushSync(() => {
setA((a) => a + 1);
});
flushSync(() => {
setB((b) => b + 2);
});
}, 0);
};
–--
このドキュメントは "Chatwork Tech Tips" の一環です。
その他の Tips も含めて @Chatwork_dev にて確認することができます 👨🏫
Discussion