React勉強した人は通るであろう、useEffectとuseLayoutEffectの違いについて。
ググってみると色んなサイトで説明がありますが、自分なりに整理しました。
- useEffectとuseLayoutEffectの違いについて
- 一般的にuseEffectが使われる理由
- useLayoutEffectの方が向いている局面
- Reactでブラウザがレンダリングされるまでの流れ
- まとめ
- 参考サイト
useEffectとuseLayoutEffectの違いについて
結論
→実行タイミングの違い。
useEffect
・非同期で実行
・コンポーネントのレンダリング後に非同期で実行されるため、コンポーネントの表示に影響を与えない操作に適している。
・使う局面としてはネットワークリクエスト、データの取得、DOMの変更、ログの出力などの遅延可能な操作を行うために適している。
useLayoutEffect
・同期的に実行
・コンポーネントのレンダリング後(仮想DOMの構築後)、DOMが更新される前に実行されるため、DOMの計算や計測、ブラウザでの描画前にスクロール位置を設定するなど、表示に関連する操作が必要な場合に使用する。
・ブラウザの描画前に実行されるため、useEffectだと発生する画面のちらつき(初期表示されてから瞬時にuseEffectによりブラウザが再描画する挙動)が避けられる。
※useEffectの画面のちらつきについては以下ブログでの説明が分かりやすいです。
useEffectのちらつきを無くしたいときの対処法【useLayoutEffect】
ただ、どのサイトでも説明されている通り、一般的にuseEffectを使うことが多く、useLayoutEffectを使う局面は限られている。
一般的にuseEffectが使われる理由
useLayoutEffectの方が向いている局面
useEffectはブラウザでの描画が完了した後に非同期操作が実行されるため、コンポーネントの表示に直接影響を与えない操作(例: ログの出力)に適している。
ただし、ブラウザは非同期操作をキューに追加して実行しており、非同期処理の順序は保証されない。ので、操作の順序が重要な場合はuseLayoutEffectが使用される。
Reactでブラウザがレンダリングされるまでの流れ
2. 実際のDOMへの変更(Reconciliation)
仮想DOMと前回のレンダリングの仮想DOMとの差分が計算され、必要なDOMの変更が特定される。この段階で実際のDOMへの変更が行われる。
3. ブラウザの描画(Painting)
DOMの変更が適用され、ブラウザが再描画を行なわれる。
まとめ
改めてuseEffectとuseLayoutEffectの実行タイミングの違いを確認
useEffect
→ブラウザの描画の後に非同期で実行される。
useLayoutEffect
→仮想DOMの構築が完了して、実際のDOMの変更の前に同期的に実行される。
大体のケースではuseEffectを使用するのが最適解。