【入門編】 依存配列におけるオブジェクト・配列の参照比較問題 – React実践ガイド

こんにちは。Reactの世界へようこそ。
Reactを学び始めると、避けては通れない壁がいくつかありますよね。その中でも、特に多くの人が「あれ、なぜかループが止まらないぞ?」「思った通りに動いてくれない!」と首をかしげるのが、`useEffect`の「依存配列」と「オブジェクト・配列の参照問題」です。

今日は、このちょっと気難しいけれど大事なルールについて、専門用語を並べる前に、まずは「お買い物の例え話」で紐解いてみましょう。

—

1. なぜ「同じもの」なのに「違う」と言われるの?

Reactの`useEffect`は、依存配列(`[]`の中身)に変化があったときだけ、中身の処理を実行します。ここで初心者の皆さんが最初につまずくのが、「中身は全く同じなのに、なぜか再実行される」という現象です。

これ、実は「見た目が同じかどうか」ではなく「箱が同じかどうか」を見ているからなんです。

例え話:双子の「お買い物リスト」

想像してください。あなたが友人に「お買い物リスト(配列)」を渡すとします。

1. 初回: あなたは紙に「牛乳」「卵」と書いて渡しました。友人(React)は「了解、買いに行くね」とメモします。
2. 2回目: あなたは全く同じ内容を「新しい紙」に書いて渡しました。
3. 友人: 「さっきと中身は同じ文字だけど、これは新しい紙だよね? じゃあ、さっきの買い出しとは別件かな?」と考えて、またお店へ走ってしまいます。

これが、Reactの中で起きている「参照の不一致」です。プログラムの世界では、中身の文字が同じでも、作られたタイミングが別なら「別の物」として扱われるのです。

—

2. 現場でよくある「やってしまいがちなミス」

Reactのコンポーネントが再レンダリングされるたびに、関数の中身は最初から最後まで「新品」になります。つまり、コンポーネントの中で定義したオブジェクトや配列は、毎回新しく作り直されているのです。

function ShoppingList() {
// コンポーネントが再描画されるたびに、この配列は「新しい箱」として生成されます
const items = [“牛乳”, “卵”];

useEffect(() => {
console.log(“買い出しに行きます!”);
}, [items]); // ここで「items」を指定すると、毎回「新しい紙」と判断されて無限に実行されます!

return

お買い物リストを表示中…

;
}

これを防ぐには、「この紙(変数)は、中身が変わらない限り同じものを使い回してね」とReactに伝えてあげる必要があります。

—

3. 解決策:Reactに「同じ箱だよ」と教えてあげる

ここで登場するのが、`useMemo`という魔法です。「この値は、計算結果を覚えておいて(メモして)、変わらない限りは以前のものを使い回してね」という指示を出せます。

`useMemo`を使った修正例

import React, { useEffect, useMemo } from ‘react’;

function ShoppingList() {
// useMemoを使うことで、itemsは再描画されても「同じ箱」として維持されます
const items = useMemo(() => [“牛乳”, “卵”], []);

useEffect(() => {
console.log(“一度だけ買い出しに行きます!”);
}, [items]); // これで、中身が本当に変わらない限り再実行されません!

return

お買い物リストを表示中…

;
}

どうでしょう? `useMemo`という「記憶の箱」に入れてあげるだけで、Reactは「あ、これは前と同じ紙だね」と納得してくれるようになります。

—

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

実務の現場では、`useMemo`を使うべきか、あるいはそもそも依存配列に直接書くべきではないのか、と迷うことがよくあります。

  • 基本は「シンプル」に: もし可能なら、`useEffect`の中に直接配列を書くか、コンポーネントの外で定数として定義しましょう。外に出せば、そもそも「再生成」という問題自体が消滅します。
  • 迷ったら`useRef`: もし「値自体は保持したいけれど、再描画のトリガーにしたくない」という特殊なケースなら、`useRef`という「Reactの再描画とは無縁な、自分専用のメモ帳」を使うのも賢い選択です。

最後に

「参照比較」という言葉は難しく聞こえますが、要は「Reactはとっても真面目な几帳面さんだから、同じものだと信じられる証拠(参照先)が必要なんだな」と思ってあげてください。

最初は誰だって「あれ、なんで?」と悩む道です。でも、一度この「箱の概念」を理解してしまえば、Reactのコードは劇的に美しく、そして速くなります。

もしコードが期待通りに動かなくても、自分を責めないでくださいね。「あ、またReact君が新しい箱だと勘違いしてるな」と気づけたなら、あなたはもう一人前のReactエンジニアへの階段を登っています。

焦らず、一歩ずつ進んでいきましょう!応援しています。

コメント

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