[React.js] - パート11: React Hooks - useEffect Hook

Ace Lennox
ReactにおけるuseEffect
フックは、関数コンポーネントで副作用を管理するための強力なツールです。副作用とは、データの取得、DOMの直接操作、タイマーの管理など、レンダリング以外の操作を指します。このガイドでは、useEffect
の使い方を具体例とともに詳しく解説します。
useEffect
とは?
useEffect
フックを使うと、Reactのレンダリングサイクル外でタスクを実行することができます。たとえば、APIリクエストやブラウザベースの操作など、アプリケーション外部とのやり取りを行う際に役立ちます。
useEffect
の仕組み
useEffect
フックは、次の2つの引数を取ります:
副作用のロジックを記述する関数。
依存配列(省略可能)。この配列によって副作用が実行されるタイミングが決まります。
useEffect(() => {
// 副作用のロジック
}, [dependencies]);
依存配列を省略すると、レンダリングごとに副作用が実行されます。
副作用の実例
例1: ローディング後にメッセージを表示
コンポーネントがレンダリングされてから2秒後にメッセージを表示する例を見てみましょう:
import { useState, useEffect } from "react";
import ReactDOM from "react-dom/client";
function WelcomeMessage() {
const [message, setMessage] = useState("");
useEffect(() => {
const timer = setTimeout(() => {
setMessage("私たちのウェブサイトへようこそ!");
}, 2000);
// メモリリークを防ぐためのクリーンアップ
return () => clearTimeout(timer);
}, []); // 初回レンダリング時のみ実行
return <h1>{message}</h1>;
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<WelcomeMessage />);
setTimeout
で遅延処理をシミュレートし、クリーンアップ関数でタイマーを解除しています。
例2: APIからデータを取得
次に、ユーザー情報をAPIから取得して画面に表示する例です:
function UserData() {
const [user, setUser] = useState(null);
useEffect(() => {
async function fetchUser() {
const response = await fetch("https://jsonplaceholder.typicode.com/users/1");
const data = await response.json();
setUser(data);
}
fetchUser();
}, []); // 初回レンダリング時のみ実行
if (!user) return <p>読み込み中...</p>;
return (
<div>
<h1>{user.name}</h1>
<p>メール: {user.email}</p>
</div>
);
}
依存配列を空にすることで、APIコールは初回レンダリング時に一度だけ実行されます。
例3: 状態に応じたタイトルの更新
クリック数に応じてドキュメントのタイトルを更新する例を見てみましょう:
function ClickTracker() {
const [clicks, setClicks] = useState(0);
useEffect(() => {
document.title = `クリック回数: ${clicks}`;
}, [clicks]); // 'clicks'が変更されるたびに実行
return (
<div>
<button onClick={() => setClicks((prev) => prev + 1)}>クリック</button>
</div>
);
}
[clicks]
を依存配列に含めることで、クリック数が変化するたびにuseEffect
が実行されます。
クリーンアップの重要性
タイマーやイベントリスナー、サブスクリプションなどの副作用は、適切にクリーンアップしないとメモリリークの原因になります。
例4: イベントリスナーのクリーンアップ
ウィンドウのサイズを追跡する例を見てみましょう:
function WindowSize() {
const [width, setWidth] = useState(window.innerWidth);
useEffect(() => {
const handleResize = () => setWidth(window.innerWidth);
window.addEventListener("resize", handleResize);
// イベントリスナーを解除する
return () => window.removeEventListener("resize", handleResize);
}, []); // マウント時とアンマウント時に実行
return <h1>ウィンドウ幅: {width}px</h1>;
}
useEffect
のベストプラクティス
依存関係を明確に: 副作用が依存するすべての状態やプロップスを必ず含める。
クリーンアップを実施: タイマーやリスナーを解除して、メモリリークを防ぐ。
不要な副作用を避ける: 計算や変換などは
useEffect
ではなく、直接レンダリングで処理する。依存配列を最適化: 必要な依存関係だけを含め、余計な再実行を防ぐ。
まとめ
useEffect
フックは、Reactコンポーネントで副作用を管理するための重要なツールです。データ取得やイベント管理、DOMの更新をクリーンかつ効率的に行うために、useEffect
を正しく使うことが鍵となります。
このガイドの例を試して、useEffect
がどのようにReactアプリをよりダイナミックにするかを体感してください!
ソースコード
このプロジェクトの完全なソースコードはGitHubで利用可能です。