はじめに
この記事では、 CSS in JS を開発している人にしか関係ない、React18の新機能 useInsertionEffectについて解説します。
useInsertionEffect とは?
useInsertionEffectは、DOMが変更される前に実行される useEffect みたいなものです。
注意点
useInsertionEffectは、CSS in JSライブラリー開発者のためのHooksです。
CSS in JSのスタイルを反映させる場所で使うことを想定されているため、他の場所ではuseEffectやuseLayoutEffectを使いましょう!
使い方
以下の例は、DOMの変更の前にスタイルを挿入するために呼び出ししている例です。
// CSS-in-JS library
import { useInsertionEffect } from 'react';
function useCSS(rule) {
useInsertionEffect(() => {
// <style>...</style>を挿入する
});
return rule;
}
useLayoutEffetより先に実行してくれるのがいい。
レンダリングの処理は以下のようになっており、useInsertionEffect は、useLayoutEffet が実行される前に実行されます。

useLayoutEffetは、画面の描画する前に実行するため、useEffectのちらつきを解決してくれくれる便利なHooksです。
useLayoutEffectの処理と同じタイミングで、CSS in JSのスタイル挿入をしてしまうと、変更前のスタイルで、useLayoutEffectの処理が行われ、useLayoutEffectで意図した通りに処理が行われません。
そのため、更新されたスタイルで、useLayoutEffectを実行させるためにも、useInsertionEffectを使ってスタイルを挿入してあげるのが良いのです。
sample
sampleでは、ボタンを押すと、ボタンの背景色が変わり、その背景色を取得しています。
その後、取得した値をボタンの文字に反映させています。
理想
こちらのsampleは理想的な状態です。
sampleの中のAdjacentStyle()では、背景色を変更し、変更したスタイルを、<style>に挿入しています。
また、getBgColor()では、背景色を取得して、テクスト変更させています。
そして、isRedの値が変わったタイミングでuseInsertionEffectとuseLayoutEffectを実行しているというサンプルです。
useLayoutEffectで処理した場合
CSS in JSのスタイルの挿入とuseLayoutEffectの処理が同じタイミングになるとこうなります。
getBgColor()が実行されるときは、まだ、スタイルが挿入されていない状態なので、
ボタンのテキストには、挿入前のbackground-colorの値が入ります。
その後、スタイルが挿入されることになるので、ボタンのbackground-colorは変わります。
そのため、#0000ffのbackground-colorなのにrgb(255,0,0)が表示され、
#ff0000のbackground-colorなのにrgb(0,0,255)が表示されるみたいな状態になります。
まとめ
この記事では、 CSS in JS を開発している人にしか関係ない、React18の新機能 useInsertionEffectについて解説しました。
useInsertionEffectは、使い方は、ほぼuseEffetやuseLayoutEffectと同じですが、
CSS in JSを開発している人向けの機能のため、useLayoutEffectより実行タイミングが早いという特徴があります。
業務ではほぼ使うことはないと思いますが、気が変わってCSS in JS開発することになったらこの記事を見返そうと思います。
最後まで読んでくださってありがとうございます!
普段はデザインやフロントエンドを中心にQiitaに記事を投稿しているので、ぜひQiitaのフォローとX(Twitter)のフォローをお願いします。