はじめに|僕がuseEffectでハマった瞬間

前回は useState について解説しました。
「状態を持たせてUIとつなげる仕組み」を理解できると、Reactの面白さが一気に広がるんですよね。
ただ、その次に出てくる useEffect がまたクセモノでした。
最初に使ったとき、正直「これ何のためにあるの?」「依存配列ってどういう意味?」と頭の中が混乱しました。
しかも、ちょっと書き方を間違えると画面が無限に再レンダリングされてブラウザが固まる…。
僕はここで一度React学習が止まりかけたのですが、落ち着いて「3つのパターン」に整理して考えたらようやく理解できるようになりました。
この記事ではその経験をもとに、初心者が理解すべき useEffect の3つの基本 をやさしく解説します!
ReactにおけるuseEffectとは?
React公式ドキュメントにはこう書かれています。
useEffect is a React Hook that lets you synchronize a component with an external system.
(useEffect はコンポーネントを外部システムと同期させるためのフックです)
ここでいう「外部システム」とは、Reactが管理していない部分のことを指します。
例えば、以下のような処理です。
- APIからデータを取得して状態に反映する
- DOMを直接操作する
- タイマーやイベントリスナーを設定する
- コンソールにログを出力する
つまり、コンポーネントのレンダリング(描画)以外で発生する処理を管理するのが useEffect です。

基本①:Reactで初回レンダリング時に処理を実行する方法
コード全文(App.js)
import { useEffect } from "react";
function App() {
  useEffect(() => {
    console.log("コンポーネントが初回表示されました");
  }, []);
  return <h1>Hello React</h1>;
}
export default App;解説
useEffect(() => {
  console.log("コンポーネントが初回表示されました");
}, []);- 第2引数の依存配列 []を空にすると「初回レンダリング時のみ」実行される
- よくある使い方は「初期データの取得」や「初期化処理」
初心者がつまずくポイント
- 依存配列 []を書かないと、レンダリングのたびに処理が走ってしまう
- その結果、予期せず無限ループになることもある
基本②:Reactで依存する値が変わったときに処理を実行する方法
コード全文(App.js)
import { useState, useEffect } from "react";
function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    console.log(`countが${count}に更新されました`);
  }, [count]);
  return (
    <div>
      <p>カウント: {count}</p>
      <button onClick={() => setCount(count + 1)}>+1</button>
    </div>
  );
}
export default App;解説
useEffect(() => {
  console.log(`countが${count}に更新されました`);
}, [count]);- 依存配列 [count]に変数を指定すると、その値が変わるたびに実行される
- countの更新に合わせて副作用を発動させたいときに便利
初心者がつまずくポイント
- 依存配列に必要な値を入れ忘れると「更新しても処理が走らない」
- 逆に不要な値を入れると「無駄に再実行される」
基本③:ReactのuseEffectでクリーンアップ処理を行う方法
コード全文(App.js)
import { useState, useEffect } from "react";
function App() {
  const [count, setCount] = useState(0);
  useEffect(() => {
    const timer = setInterval(() => {
      setCount((prev) => prev + 1);
    }, 1000);
    return () => {
      clearInterval(timer);
      console.log("タイマーを停止しました");
    };
  }, []);
  return <h1>{count} 秒経過</h1>;
}
export default App;解説
useEffect の中で return () => {...} と書くと、その部分が「後片付け(クリーンアップ処理)」として動きます。
具体的には、このタイミングで実行されます
- コンポーネントが画面から消えるとき(アンマウント時)
- 依存する値が変わり、同じ useEffectが再実行される直前
実際の挙動のイメージ
この例では setInterval で1秒ごとに count を増やしています。
- マウント時(初回表示時)
 → タイマーが作られてcountが動き出す
- コンポーネントが消えるとき
 →return内の処理が呼ばれて、clearInterval(timer)でタイマーが止まる
 →console.log("タイマーを停止しました")が出力される
つまり、Reactが「このコンポーネントもう使わないな」と判断したときに、自動で掃除してくれる仕組みです。
クリーンアップがないとどうなるか?
もし return () => {...} を書かなかったら、コンポーネントが消えてもタイマーは動き続けます。
例えば以下のような不具合が起きます
- ページを切り替えたのに裏で setIntervalが動き続けている
- イベントリスナーを重複登録してしまい、同じ処理が何度も呼ばれる
- 結果として「メモリリーク」や「動作の不安定化」につながる
Reactは「部品が消えるときに後片付けをしてね」と言っているわけです。
まとめ|React初心者が理解すべきuseEffectの3つの基本

この記事では、useEffect の基本を3つに分けて解説しました。
- 初回レンダリング時に実行する → 依存配列を空 []にする
- 特定の値が変わったときに実行する → 依存配列に変数を指定
- クリーンアップ処理を行う → returnに関数を書く
僕自身、最初は「なぜこんなにややこしいんだ…」と思っていました。
でも、この3つのパターンを理解したら、逆に「Reactってよくできてるな」と感心するようになりました!
次回は「イベント処理とフォームの扱い方」について解説していこうと思います!















コメントを残す