useInsertionEffect 完全入門【React】CSS-in-JSライブラリ向けの特殊フック
ReactのuseInsertionEffectとは何か、CSS-in-JSライブラリでのスタイル挿入における役割を解説。一般的なアプリ開発での使用場面と、useEffectやuseLayoutEffectとの実行タイミングの違いも紹介します。
React のフックの中でも、useInsertionEffect は一般的なアプリ開発ではほとんど使うことのない特殊なフックです。
このフックは主に CSS-in-JS ライブラリの開発者を対象としており、スタイルを DOM に挿入するタイミングを最適化するために設計されています。「なんのためにあるのか」を理解することで、React のレンダリング仕組みへの理解も深まります。
この記事でわかること:
useInsertionEffectが生まれた背景useEffect・useLayoutEffectとの実行タイミングの違い- CSS-in-JS ライブラリでの使用例
- 一般アプリ開発者が知っておくべきポイント
useInsertionEffect とは?
useInsertionEffect は、レイアウトエフェクトが発火する前に DOM にスタイルを挿入するためのフックです。
useInsertionEffect(setup関数, 依存配列);useEffect や useLayoutEffect と同じ API ですが、実行タイミングが異なります。
3つのエフェクトの実行タイミング
① React が DOM を更新する
↓
② useInsertionEffect が実行される ← 最初に実行(スタイル挿入)
↓
③ useLayoutEffect が実行される ← レイアウト測定
↓
④ ブラウザが画面を描画する
↓
⑤ useEffect が実行される ← 描画後
useInsertionEffect が最も早いタイミングで実行されることで、他のエフェクトが実行される時点ではスタイルがすでに適用された状態になります。
なぜ必要なのか?
CSS-in-JS ライブラリ(emotion、styled-components など)は、コンポーネントのレンダリング時にスタイルを動的に生成して DOM に挿入します。
もし useLayoutEffect の中でスタイルを挿入すると、以下の問題が起きます:
① DOM 更新
② useLayoutEffect 実行中にスタイル挿入
→ ブラウザが強制的にスタイルを再計算する(パフォーマンス低下)
③ ブラウザ描画
useInsertionEffect を使うことで、レイアウト計算が始まる前にスタイルを挿入でき、ブラウザの強制的なスタイル再計算を避けられます。
CSS-in-JS ライブラリでの使用例
// CSS-in-JS ライブラリの内部実装イメージ
function useCSS(rule) {
useInsertionEffect(() => {
// レイアウトエフェクトより前にスタイルを DOM に挿入する
if (!isInserted.has(rule)) {
isInserted.add(rule);
document.head.appendChild(getStyleForRule(rule));
}
});
return rule;
}
// コンポーネントからの利用
function Button() {
const className = useCSS("button { color: blue; }");
return <button className={className}>クリック</button>;
}重要な制約
useInsertionEffect には通常のエフェクトにはない制約があります:
| 制約 | 説明 |
|---|---|
| state の更新不可 | エフェクト内から state を更新できない |
| ref 未アタッチ | 実行時点では ref はまだ DOM にアタッチされていない |
| クライアントのみ | サーバーサイドレンダリング中は実行されない |
// ❌ NG:useInsertionEffect 内で state を更新してはいけない
useInsertionEffect(() => {
setState(something); // エラーになる
});一般的なアプリ開発者へのアドバイス
useInsertionEffect はライブラリ開発者向けのフックです。アプリ開発では通常使いません。
| 用途 | 使うフック |
|---|---|
| データ取得・イベントリスナー | useEffect |
| DOM 測定・レイアウト調整 | useLayoutEffect |
| CSS-in-JS スタイル挿入(ライブラリ内部) | useInsertionEffect |
styled-components や emotion などの CSS-in-JS ライブラリを使う側の立場では、このフックの存在を意識する必要はありません。ライブラリが内部で適切に処理してくれます。
まとめ
useInsertionEffectは CSS-in-JS ライブラリ開発者向けの特殊なフックuseLayoutEffectよりも早いタイミングでスタイルを DOM に挿入できる- ブラウザの強制スタイル再計算を防ぎ、パフォーマンスを向上させる
- state の更新や ref へのアクセスはできない
- 一般的なアプリ開発では使わなくてよい
PR
useInsertionEffect 公式ドキュメントで詳細を確認しよう
useInsertionEffectの詳細仕様や、CSS-in-JSライブラリへの組み込み例は公式ドキュメントで確認できます。
useInsertionEffect 公式ドキュメントを見る →