やあ。Reactの世界へようこそ。
フロントエンドの深淵を覗き込んでいる君に、今日は「Reactで一番つまずきやすいけれど、ここさえ乗り越えれば一気にプロの顔になれる」という、`useEffect`と「依存配列(Dependency Array)」の話をしよう。
「`eslint-plugin-react-hooks`の警告がうるさくて、つい`// eslint-disable-next-line`で黙らせてしまったことはないかい?」
もしそうなら、大丈夫。みんな一度は通る道だ。でも、今日でその「見て見ぬふり」とはお別れしよう。なぜあの警告が出るのか、その理由を一緒に紐解いていくよ。
—
1. 依存配列は「魔法のトリガー」ではない、「観測ポイント」だ
まず、`useEffect`が何をしているかをイメージしてみよう。
これは「特定の何かが変わったときに、自動で動くお掃除ロボット」のようなものだ。
useEffect(() => {
console.log(“お掃除開始!”);
}, [依存配列]); // ここがポイント!
多くの初心者は、この`[ ]`を「実行するタイミングを指定する場所」だと勘違いしてしまう。違うんだ。これは「どの値の変化を監視して、副作用(お掃除)を再起動するかを決める観測ポイント」なんだよ。
なぜ「中身を空」にしたり「省略」したりしてはいけないのか?
たとえば、冷蔵庫の中身(state)をチェックして買い物リストを作るアプリを作るとしよう。
依存配列に「冷蔵庫の中身」を入れ忘れると、どうなると思う?
- 現実の世界: 冷蔵庫に卵がなくなったのに、リストが更新されない(バグの発生)。
- Reactの世界: 画面には古いデータが表示されたまま、ユーザーは「あれ?動かないな」と混乱する。
`eslint-plugin-react-hooks`(exhaustive-depsルール)は、「君、冷蔵庫の中身が変わったのに、リストを更新しなくていいのかい? 忘れ物をしてるよ!」と親切に教えてくれている「監視役のAI」なんだ。これを無視するのは、羅針盤を持たずに航海に出るようなものだよ。
—
2. 依存配列の欠落が引き起こす「悲劇」
一番多いのは、「関数の中身を使っているのに、配列に入れない」というケースだ。
const [count, setCount] = useState(0);
useEffect(() => {
const timer = setInterval(() => {
// count を参照しているのに、依存配列に入れていない!
console.log(`現在のカウントは: ${count}`);
}, 1000);
return () => clearInterval(timer);
}, []); // 依存配列が空っぽだと…?
このコード、動かしてみると最初は動く。でも、`count`がいくら増えても、コンソールにはずっと「0」と表示され続けるんだ。なぜなら、この`useEffect`は「最初に生まれた時の`count`の値」を固めて握りしめてしまっているからだよ。これを「クロージャの罠」と呼ぶんだ。
—
3. どうすればいい? ベストプラクティスを授けよう
警告が出たとき、無理やり消すのではなく、以下の順で対処してみてほしい。
① シンプルに配列に入れる
一番の正解は、素直に`[count]`と書き足すこと。これで、Reactは「`count`が変わるたびに、お掃除ロボット(エフェクト)を新しく作り直そう」と判断してくれる。
② 「関数」が原因なら `useCallback` を使う
これが中級者へのステップアップだ。「関数が再生成されるたびにエフェクトが動いてしまう!」と悩んだら、関数自体を`useCallback`でメモ化(固定化)してあげよう。
const fetchData = useCallback(() => {
// データを取ってくる処理
}, [id]); // idが変わらない限り、この関数は作り直されない
useEffect(() => {
fetchData();
}, [fetchData]); // これなら警告も消えるし、動きも正確だ!
③ どうしても含めたくないなら「ロジック」を外に出す
もし「この値が変わるたびにエフェクトを動かしたくないけど、値は使いたい」という場面があるなら、それは「その処理は`useEffect`の中に書くべきではない」というReactからのサインかもしれない。
関数をコンポーネントの外に出したり、`useRef`を使って「値は参照するけど再実行のトリガーにはしない」という裏技を使うのも一つの手だ。
—
最後に:警告は「敵」じゃなく「師匠」だ
`eslint-plugin-react-hooks`の警告は、決して君のコードを否定しているわけじゃない。「君が書いた意図と、Reactが動く仕組みの間にズレがあるよ」と、優しく教えてくれているんだ。
最初は面倒に感じるかもしれない。でも、このルールを愛して付き合っていくと、Reactのデータの流れが手に取るようにわかるようになる。そうすれば、君はもう初心者卒業だ。
次に警告が出たら、こうつぶやいてみてほしい。
「おっ、教えてくれてありがとう。さて、どう直してやろうか?」
その瞬間から、君のコードはグッと堅牢で、プロフェッショナルなものに変わるはずだよ。応援しているよ!

コメント