【入門編】 useLayoutEffectとuseEffectの実行タイミングの差異 – React実践ガイド

やあ、こんにちは。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

この要素の幅は {width}px です

;
};

—

4. チーフアーキテクトからのアドバイス

実務で僕が後輩に伝えているのは、「まずは全部 `useEffect` で書いてみな」ということ。

理由はシンプル。`useLayoutEffect` は、処理が終わるまでブラウザの画面更新を待たせてしまうからだ。もしその中で重たい計算を走らせたら、サイト全体の動きがモッサリしてしまう。だから、「本当にチラつきが許されない時」以外は、あえて使わないのが「プロの節度」なんだ。

  • APIからデータを取ってくる? → `useEffect`(通信は遅いから、描画を待たせちゃダメ!)
  • 画面のサイズに合わせてメニューの位置を微調整する? → `useLayoutEffect`(ズレて見えるとダサいから!)

こうやって役割を分けてあげれば、君のReactアプリは驚くほど滑らかで、心地よい挙動になるはずだよ。

—

最後に:つまずくことは「成長」のサイン

最初は誰だって、タイミングの制御に悩むものだ。でも大丈夫。今日こうして「描画の裏側」を意識できた君は、もう一歩上のエンジニアに近づいている。

もしコードを書いていて「あれ?今チラついた?」と感じたら、それは君の目が肥えてきた証拠。その時は、この記事を思い出して `useLayoutEffect` のスイッチをカチッと切り替えてみてほしい。

君が作るプロダクトが、ユーザーにとって最高に心地よい体験になりますように。応援しているよ!

コメント

タイトルとURLをコピーしました