ReactのuseEffectで依存配列を正しく指定する方法!初心者向け完全ガイド
生徒
「先生、useEffectってよく出てきますけど、依存配列っていうのがよく分からないです。空にしてもいいって聞いたり、変数を入れないといけないって聞いたりして混乱しています…」
先生
「確かに依存配列はReact初心者がつまずきやすいポイントです。簡単に言うと、依存配列は『この値が変わったらもう一度処理を実行してね』とReactに伝えるためのものです。」
生徒
「なるほど!でも、具体的にどう指定すればいいんですか?」
先生
「それでは、依存配列の役割と正しい指定方法を、初心者でも分かるように例を使って説明していきましょう。」
1. useEffectと依存配列の基本
ReactのuseEffectは、コンポーネントが描画されたときや特定の値が変わったときに動作する仕組みです。そのときに「何をきっかけに処理をもう一度動かすか」を決めるのが依存配列です。
例えば、料理で「ご飯が炊けたら次の料理を始める」と考えると、ご飯の状態が「依存」になっています。同じように、Reactでも「特定の変数が変わったら再度処理を走らせる」と設定します。
2. 依存配列を空にする場合
依存配列を空にすると、処理は最初の1回だけ実行されます。これは「画面が表示されたときだけ動かしたい処理」に向いています。例えば初回ロード時に一度だけAPIを呼びたいときです。
useEffect(() => {
console.log("最初の1回だけ実行されます");
}, []);
3. 特定の値に依存させる場合
依存配列に変数を指定すると、その変数が変わるたびに処理が再実行されます。例えば、ユーザーが入力した名前が変わったら処理を実行する、というようなケースです。
import React, { useState, useEffect } from "react";
function NameWatcher() {
const [name, setName] = useState("");
useEffect(() => {
console.log("名前が変わりました:", name);
}, [name]);
return (
<div>
<input value={name} onChange={(e) => setName(e.target.value)} />
<p>入力中の名前: {name}</p>
</div>
);
}
export default NameWatcher;
4. 依存配列を指定しない場合の危険性
もし依存配列を省略した場合、useEffectの処理は「毎回の描画」で実行されます。これは無限ループやパフォーマンス低下につながる可能性があります。
例えばAPIを呼び出す処理を書いた場合、画面が再描画されるたびにAPIが呼ばれてしまい、サーバーに負担をかけることになります。そのため、依存配列は必ず意識して書くことが大切です。
5. 複数の依存を指定する場合
依存配列は一つだけでなく複数の変数を指定することもできます。その場合は、いずれかが変わったときに処理が再実行されます。
useEffect(() => {
console.log("nameかageのどちらかが変わりました");
}, [name, age]);
このように複数の依存を指定すれば「この二つの状態が変わったら動作する」という制御が可能です。
6. useCallbackやuseMemoと依存配列
初心者がつまずきやすいのが「関数やオブジェクトを依存配列に入れるべきかどうか」です。Reactでは関数やオブジェクトは毎回新しく作られるため、依存配列にそのまま入れると無限ループになることがあります。
その場合はuseCallbackやuseMemoを使って関数や値をメモ化(保存して再利用する仕組み)し、不要な再実行を防ぐことが大切です。
7. 初心者が守るべき依存配列のルール
- 依存配列を空にするときは「最初の1回だけ」でよい処理か確認する
- 変数を入れるときは「その値が変わるたびに処理を動かしたいか」を考える
- 依存を省略すると無限ループの原因になるので注意
- 関数やオブジェクトを依存にする場合は
useCallbackやuseMemoを検討する
これらを意識して書けば、ReactのuseEffectを安全に使いこなせるようになります。
まとめ
useEffectと依存配列の考え方をしっかり整理しよう
この記事では、ReactのuseEffectにおける依存配列の役割と、正しく指定するための考え方について詳しく学んできました。 useEffectは、画面が表示されたあとや、特定の状態が変化したタイミングで処理を実行できる便利な仕組みですが、 依存配列を正しく理解していないと、思わぬタイミングで処理が何度も実行されたり、 無限ループやパフォーマンス低下の原因になったりします。 そのため、依存配列は「なんとなく書くもの」ではなく、 「どの値が変わったときに、この処理を実行したいのか」を明確に表す重要な設定だと理解することが大切です。
依存配列を空にした場合は、コンポーネントが最初に表示されたときだけ処理が実行されます。 これは初期データの取得や、初回表示時の設定処理などにとても向いています。 一方で、特定の変数を依存配列に入れると、その変数が変化するたびにuseEffectが再実行されます。 この仕組みを正しく使えば、ユーザーの入力や状態変更に合わせて、必要な処理だけを安全に実行できます。
依存配列を省略するリスクを理解する
初心者が特につまずきやすいのが、依存配列を省略してしまうケースです。 依存配列を書かない場合、useEffectは再レンダリングのたびに実行されます。 状態更新を含む処理があると、描画と処理が何度も繰り返され、 画面が重くなったり、意図しない動作が発生したりします。 そのため、useEffectを書くときは「この処理はいつ動くべきか」を必ず意識し、 依存配列を省略しない習慣を身につけることが重要です。
useEffect(() => {
console.log("countが変わったときだけ実行されます");
}, [count]);
このように依存配列を明示的に指定することで、 処理の実行タイミングがはっきりし、後からコードを見返したときにも理解しやすくなります。 ReactのuseEffectは自由度が高い分、依存配列の指定がコードの品質を大きく左右します。
関数やオブジェクトと依存配列の関係
記事の後半で触れたように、関数やオブジェクトを依存配列に含める場合は特に注意が必要です。 Reactでは、再レンダリングのたびに新しい関数やオブジェクトが生成されるため、 そのまま依存配列に入れると「毎回変わった」と判断され、useEffectが何度も実行されてしまうことがあります。 これを防ぐためにuseCallbackやuseMemoを使って値や関数を安定させる考え方は、 Reactの仕組みを理解するうえで非常に重要なポイントです。
初心者のうちは難しく感じるかもしれませんが、 「依存配列に入れたものは、本当に変化を監視したいものか」という視点を持つだけでも、 バグや無限ループを大きく減らすことができます。 useEffectと依存配列はセットで考えるものだと覚えておくと、 Reactのコードがぐっと読みやすくなります。
生徒
「useEffectの依存配列って、ただ書けばいいものだと思っていましたが、 実行タイミングを決める大事な役割があるんですね。」
先生
「その通りです。依存配列はuseEffectの動きをコントロールするスイッチのようなものです。 どの値が変わったら処理を動かすのかを、はっきりさせることが大切です。」
生徒
「空の依存配列と、省略した場合の違いもようやく分かりました。 省略すると毎回動いてしまうのは、確かに怖いですね。」
先生
「そうですね。まずは安全な書き方を身につけて、 必要なタイミングだけ処理が動くように意識すると、Reactがずっと扱いやすくなりますよ。」