やあ、こんにちは。Reactの世界へようこそ。
最初は「あれ?なんで画面がチラつくんだろう?」「思った通りのタイミングで動いてくれないな」なんて悩むことも多いよね。でも安心して。それは君が、Reactという魔法の仕組みと、ブラウザが絵を描く「物理的な限界」の狭間で、一生懸命戦っている証拠だから。
今日は、そんな君が必ずぶつかる壁、「`useEffect` と `useLayoutEffect`、結局どっちを使えばいいの?」という疑問について、現場の知恵を交えて紐解いていこう。
—
1. 舞台裏を想像してみよう:Reactとブラウザの「お絵描き」
まず、ブラウザが画面を表示するまでの流れを、「レストランのキッチン」に例えてみよう。
1. 注文(データの変更): 「この料理を作って!」と注文が入る。
2. 調理(DOMの更新): キッチンで材料(HTML要素)を並べ替える。
3. 盛り付け(ペイント): 完成した料理をお皿に乗せて、お客様(ユーザー)のテーブルに運ぶ。
Reactの `useEffect` は、いわば「料理をお客さんに運んだ後に、『あ、そういえば調味料を持ってくるのを忘れたな』と気づいて、あとからこっそり追加する」ような存在なんだ。
一方で `useLayoutEffect` は、「盛り付けが終わる寸前、『ちょっと待って、このパセリを乗せてからじゃないと完成させないぞ!』とキッチンで踏みとどまる」ような役割を果たす。
—
2. なぜ「チラつき」が起きるのか?
`useEffect` は、ブラウザが画面を描き終わった(ペイントした)後に動く。だから、もしその中で「画面の高さに合わせて要素の場所を動かす」なんてことをすると、こんなことが起きるんだ。
1. ブラウザが「よし、とりあえず真っ白な状態で表示しよう」と描く。
2. その直後、`useEffect` が「やっぱりここだ!」と要素をずらす。
3. ユーザーには「ガクッ」と要素が動く瞬間が見えてしまう。
これが、いわゆる「画面のチラつき(Layout Thrashing)」の正体だよ。
—
3. 使い分けの極意:こう使い分ければ迷わない!
結論から言えば、「95%は `useEffect` でOK。残りの5%だけ `useLayoutEffect` を使えばいい」。
いつ `useLayoutEffect` を出すべき?
- 画面上に要素を描画する前に、「どうしてもそのサイズや位置を正確に知っておかないと、最初から配置がズレてしまう」という場合。
- 例えば、ツールチップ(吹き出し)をマウスの近くにピタリと表示させたい時などだね。
サンプルコードで比較してみよう
import React, { useState, useEffect, useLayoutEffect, useRef } from ‘react’;
const Box = () => {
const [width, setWidth] = useState(0);
const elementRef = useRef(null);
// useEffectは「あとから」実行されるので、もしここでDOMを操作して
// 画面位置を変えると、ユーザーは一瞬のズレを見てしまう可能性がある
useEffect(() => {
console.log(“useEffect: 画面描画が終わった後に動くよ!”);
}, []);
// useLayoutEffectは「描画の前」に実行される。
// DOMのサイズを測って、それを元に何かを調整したい時はこっち!
useLayoutEffect(() => {
if (elementRef.current) {
// 画面がユーザーに見える前に幅を測って処理を完了させる
const w = elementRef.current.getBoundingClientRect().width;
setWidth(w);
console.log(“useLayoutEffect: 描画直前に計算完了!チラつき知らず!”);
}
}, []);
return
;
};
—
4. チーフアーキテクトからのアドバイス
実務で僕が後輩に伝えているのは、「まずは全部 `useEffect` で書いてみな」ということ。
理由はシンプル。`useLayoutEffect` は、処理が終わるまでブラウザの画面更新を待たせてしまうからだ。もしその中で重たい計算を走らせたら、サイト全体の動きがモッサリしてしまう。だから、「本当にチラつきが許されない時」以外は、あえて使わないのが「プロの節度」なんだ。
- APIからデータを取ってくる? → `useEffect`(通信は遅いから、描画を待たせちゃダメ!)
- 画面のサイズに合わせてメニューの位置を微調整する? → `useLayoutEffect`(ズレて見えるとダサいから!)
こうやって役割を分けてあげれば、君のReactアプリは驚くほど滑らかで、心地よい挙動になるはずだよ。
—
最後に:つまずくことは「成長」のサイン
最初は誰だって、タイミングの制御に悩むものだ。でも大丈夫。今日こうして「描画の裏側」を意識できた君は、もう一歩上のエンジニアに近づいている。
もしコードを書いていて「あれ?今チラついた?」と感じたら、それは君の目が肥えてきた証拠。その時は、この記事を思い出して `useLayoutEffect` のスイッチをカチッと切り替えてみてほしい。
君が作るプロダクトが、ユーザーにとって最高に心地よい体験になりますように。応援しているよ!

コメント