第59章:見張りリスト []
この章では、
useEffect(() => { ... }, [])が「最初の1回だけやってね」という意味になること- どんなタイミングでそれを使うと便利か
- 「なんで ESLint に怒られるの?🥺」をざっくり理解すること
- Strict Mode だと「2回動いてるように見える」理由
をゆる〜く押さえていきます💪
1️⃣ おさらい:useEffect と「見張りリスト」って?
useEffect は「画面の表示以外の仕事(副作用)」をやらせるためのフックでしたね。
第58章でやったとおり、第二引数の「見張りリスト(依存配列・dependency array)」が
- いつその処理をもう一度動かすか
を決めています。(react.dev)
パターンとしてはこんな感じ👇
- 依存配列なし:
useEffect(() => { ... })→ 毎回のレンダー後に 実行 []:useEffect(() => { ... }, [])→ 最初の1回だけ 実行[someState]:useEffect(() => { ... }, [someState])→ 最初の1回 +someStateが変わるたび 実行(Strapi)
この章はこのうち
「[] を渡したとき」専用のお話です🌟
2️⃣ [] の意味:「初回マウント時だけやってね」
コードの形はこれ👇
import { useEffect, useState } from "react";
function MountOnceDemo() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("🎉 コンポーネントが初めて表示されました!");
}, []); // ← 見張りリストが空!
return (
<div>
<p>カウント: {count}</p>
<button onClick={() => setCount((prev) => prev + 1)}>
+1する
</button>
</div>
);
}
export default MountOnceDemo;
ポイントはここです👇
-
useEffect(() => { ... }, [])- 最初にコンポーネントが画面に出たあと にだけ実行
- その後、
countが何回変わって再レンダーされても → この Effect は もう呼ばれない
クラスコンポーネントでいうと componentDidMount 的な動きと思ってOKです✨(Strapi)
3️⃣ 実験:App.tsx に組み込んでみよう 🧪
ちょっとだけ手を動かして、挙動を体感してみましょう。
3-1. コンポーネントを作る
src/MountOnceDemo.tsx を作って、さっきのコードをコピペします✍️
(ファイル名やフォルダ名はお好きにどうぞ〜)
3-2. App.tsx から呼び出す
import MountOnceDemo from "./MountOnceDemo";
function App() {
return (
<div>
<h1>第59章テスト ✨</h1>
<MountOnceDemo />
</div>
);
}
export default App;
3-3. 動きを観察 👀
- ターミナルで
npm run devを実行 - ブラウザでアプリを開く
- DevTools のコンソールを開く
- 画面が表示された瞬間に
→
🎉 コンポーネントが初めて表示されました!が 一度だけ 出ているはず - ボタンを何回押しても
→ ログは増えない(
useEffectは動いていない)
「初回だけ仕事して、あとは静かにしてるスタッフ」みたいなイメージです🤵♀️
4️⃣ 時系列で見る:Mermaid 図でイメトレ 🧠✨
「いつ動いて、いつ動かないのか」を図で見てみましょう。
- 最初のレンダー後 →
useEffectが 1回だけ 動く - そのあとの再レンダーでは →
[]のおかげで 完全スルー
という流れがつかめればOKです🙆♀️
5️⃣ どんな時に [] を使う?💡
[] は「初期設定だけしたいとき」に向いています。
例としては…
- ✅ ページを開いたタイミングで一度だけログを送る
- ✅ 一度だけイベントリスナーを登録する(
addEventListenerなど) - ✅ 一度だけ初期値を外から取ってくる(
localStorageからテーマ設定など)(DEV Community)
ただし、注意ポイント があります⚠️
⚠️ 中で「変わる値(state / props)」を読むときは要注意
useEffect の依存配列は、本来
「Effectの中で読む すべての 状態やpropsは、ここに書きましょう」
というルールがあります。(react.dev)
もし [] にしているのに、中で count を読んだりすると…
- ESLint に → “React Hook useEffect has a missing dependency” みたいに怒られたりします😇(Kinsta®)
これは
「
countを読んでるのに、[count]って書いてないよ?」
という指摘です。
なので [] で書くときは:
- 一度きりの初期化
- 変わらない値だけを扱う処理
に絞るのが安全です💡
6️⃣ 「え?2回動いてない?」Strict Mode の小ネタ 🤔
React 18 以降、開発モードで StrictMode がオンになっていると
マウント → アンマウント → もう一回マウント
という「わざとの2回試し」が行われることがあります。
その結果、useEffect(..., []) の処理が 開発中だけ 2回動いているように見える ことがあります。(OneClick IT Consultancy)
- 本番ビルド(
npm run build→ deploy)では → 通常どおり 1回だけ 実行 - 開発中だけ「ストレステスト」されてるイメージです🏋️♀️
なので、
「コンソールログが2回出るんだけど!?バグ!?」
と慌てなくて大丈夫です。 Strict Mode の仕様 だと思っておいてOKです✨
7️⃣ ミニ練習 📝(自分で書いてみよう)
時間があれば、次の2つを自分で作ってみてください:
🏅 練習1:タイトル変更
TitleOnMount.tsxを作る- 中で
useEffect(() => { document.title = "React v19 勉強中🎓"; }, []);を書く - ページを開いたとき 1回だけ タイトルが変われば成功!
→ 「あ、これが“初回だけ”か〜」が実感できればOK。
🏅 練習2:一度だけアラート
AlertOnMount.tsxを作るuseEffectの中でalert("ようこそ!このページは第59章の練習ページです✨");- 再レンダーしても(ボタン押しても)アラートが 増えない ことを確認
まとめ 🎀
useEffect(() => { ... }, [])→ コンポーネントが 最初に画面に出たときだけ 実行される- 初期設定や一度きりの処理に使うと便利✨
- 中で「変わる値」を読むなら、本来は依存配列に書く必要がある
- Strict Mode のせいで、開発中だけ2回動いてるように見えることもあるけど → 本番では1回なのであわてなくてOK👌
次の章では、[state] みたいに「特定の値が変わったときだけ動く」パターンを見ていきます。
[] と [something] の違いが分かると、useEffect が一気に扱いやすくなりますよ〜🌈