🏁 はじめに
Reactを学び始めたとき、「useEffectっていつ動くの?」「依存配列ってなに?」と思ったことはありませんか?
useEffectはReact開発で最も重要なフックの一つですが、最初に理解しづらいポイントでもあります。
この記事では、初心者の方に向けて👇のようにステップ形式で解説します。
1️⃣ useEffectの基本構文
2️⃣ 依存配列の動作を図で理解
3️⃣ クリーンアップ関数の役割
4️⃣ 実践例(API取得)
5️⃣ カスタムフック化で再利用
💻 前提条件
- React(Hooks)の基礎を知っている
- useStateを使ったことがある
- 開発環境(Vite / CRA)が用意できる
🎯 今回の目標
この記事を読み終えると、次のことができるようになります👇
✅ useEffectの役割を説明できる
✅ 依存配列の動きを理解できる
✅ クリーンアップ関数を正しく使える
✅ カスタムフックに発展できる
⚙️ useEffectとは?
useEffectは、 レンダーとは直接関係のない「副作用処理(Side Effect)」 を行うためのフックです。
たとえば…
- API通信
- イベントリスナー登録
- タイマー
- DOM操作
これらは「副作用」にあたります。
🧩 基本構文
useEffect(() => {
// 実行したい処理
return () => {
// クリーンアップ処理(後片付け)
};
}, [依存配列]);
🧠 第2引数(依存配列) が重要!
ここに指定した値が変化したときのみ再実行されます。
空配列[]なら「初回のみ」実行。
📘 基本例:マウント時だけ実行
import { useEffect } from "react";
function HelloEffect() {
useEffect(() => {
console.log("コンポーネントがマウントされました!");
}, []);
return <h1>Hello useEffect!</h1>;
}
🟢 ポイント
依存配列が空 → コンポーネント表示時に一度だけ実行。
componentDidMountと同じ動きです。
🔁 【図解】依存配列の仕組みを理解しよう
コード例
useEffect(() => {
console.log("countが変化しました!");
}, [count]);
図で見る依存配列の動き
🧩 動きの流れ
- 初回レンダーで実行される
- countが更新されると再度実行
- countが変わらなければ再実行されない
👉 無駄な再レンダーを防ぎ、パフォーマンスを保つために依存配列が重要!
🧹 クリーンアップ関数とは?
useEffectの中で返す関数は、 アンマウント時や再実行前に呼ばれる「後片付け処理」 です。
例:タイマーやイベントリスナーの解除など。
import { useEffect, useState } from "react";
function Timer() {
const [count, setCount] = useState(0);
useEffect(() => {
console.log("タイマー開始");
const timer = setInterval(() => {
setCount((prev) => prev + 1);
}, 1000);
return () => {
console.log("タイマー停止");
clearInterval(timer);
};
}, []);
return <p>経過秒数: {count}</p>;
}
🧠 イメージ
returnで返した関数が「片付け係」
再レンダーや削除時に呼ばれて、不要な処理を止める
🌐 実践例:APIからデータを取得する
import { useState, useEffect } from "react";
function UserList() {
const [users, setUsers] = useState([]);
useEffect(() => {
async function fetchUsers() {
const res = await fetch("https://jsonplaceholder.typicode.com/users");
const data = await res.json();
setUsers(data);
}
fetchUsers();
}, []);
return (
<div>
<h2>ユーザー一覧</h2>
<ul>
{users.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
</div>
);
}
🟢 ポイント
データ取得などの「副作用」はuseEffect内で行う
空の依存配列[]で「初回のみ」取得
https://jsonplaceholder.typicode.com/users
上記から得られるデータは、JSONPlaceholder という無料のオンラインREST API サービスが提供しているサンプルデータになります。
🧩 応用:カスタムフック化で再利用!
useEffectを使ったデータ取得を、カスタムフックにまとめることで再利用できます。
import { useState, useEffect } from "react";
function useFetch(url) {
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const res = await fetch(url);
const json = await res.json();
setData(json);
};
fetchData();
}, [url]);
return data;
}
export default function App() {
const users = useFetch("https://jsonplaceholder.typicode.com/users");
if (!users) return <p>読み込み中...</p>;
return (
<ul>
{users.map((u) => (
<li key={u.id}>{u.name}</li>
))}
</ul>
);
}
🧠 メリット
- 同じロジックを複数コンポーネントで使える
- コードがスッキリする
- テスト・保守が簡単になる
💡 対策
- 更新処理をuseEffectの外に出す
- 依存配列を正しく指定
🧭 まとめ
| 状況 | 依存配列 | 動作 |
|---|---|---|
| 初回だけ実行 | [] |
マウント時のみ |
| 値が変わるたび実行 | [依存配列] |
依存値の変化時 |
| 常に実行(非推奨) | 省略 | 毎レンダー |
| クリーンアップ | return () => {...} |
再実行前・削除時 |
✨ 最後に
最初は少し難しく感じるかもしれませんが、「いつuseEffectが実行されるか」を意識することが理解の第一歩です。
最後までご覧いただきありがとうございます。今後も少しずつ勉強記録も兼ねて投稿していきますので、よろしくお願いします。