概要: このチュートリアルでは、ReactのuseEffect()フックについて詳しく学び、その正しい使い方と使用タイミングを理解します。
React useEffectフックの理解
Reactにおいて、副作用とは、データフェッチ、手動DOM操作、またはコンポーネントの外部に影響を与えるその他の操作のことです。
関数コンポーネントで副作用を実行するには、useEffectフックを使用します。useEffectフックを使用するには、まずreactライブラリからインポートします。
import { useEffect } from 'react';Code language: JavaScript (javascript)次に、次の構文でコンポーネント内で使用できます。
useEffect(setup, dependencies)Code language: JavaScript (javascript)useEffectフックは、2つの引数を取る関数です。
setupは、実行したい副作用を含むメイン関数です。dependenciesは、setup関数を実行するタイミングを決定する、依存値のオプションの配列です。useEffectフックは、dependencies配列で指定されたitemsに基づいてsetup関数を実行します。
setup関数は、オプションでクリーンアップ関数を返すことができます。
return cleanup;Code language: JavaScript (javascript)Reactは、コンポーネントがアンマウントされる前、またはsetupが再実行される前(初回を除く)にcleanup関数を実行します。
cleanup関数には、インターバルのクリアやネットワークリクエストのキャンセル(AbortController)など、リソースをクリーンアップするためのコードを含めることができます。
通常、useEffectフックは次のように記述します。
useEffect(() => {
// Side effect code here
return () => {
// Cleanup code here (optional)
};
}, [dependencies]);Code language: JavaScript (javascript)この構文では、setup関数にアロー関数を定義します。
() => {
// Side effect code here
return () => {
// Cleanup code here (optional)
};
}Code language: JavaScript (javascript)そして、dependencies配列に値を記述します。
[dependencies]Code language: JavaScript (javascript)エフェクトを一度だけ実行する
コンポーネントのマウント時にエフェクト(または関数)を一度だけ実行するには、dependencies配列として空の配列を使用します。
useEffect(() => {
// This code runs once
}, [])Code language: JavaScript (javascript)実際には、このパターンはコンポーネントの初回レンダリング時に関数を実行するために使用します。たとえば、コンポーネントのマウント時に一度だけAPIからデータをフェッチする関数を実行できます。
次のUserListコンポーネントは、APIエンドポイントhttps://jsonplaceholder.typicode.com/usersを呼び出すことで、ユーザーのリストを表示します。
import React, { useEffect, useState } from 'react';
export default function UserList() {
const [users, setUsers] = useState([]);
const fetchUsers = async () => {
const url = 'https://jsonplaceholder.typicode.com/users';
const response = await fetch(url);
const data = await response.json();
setUsers(data);
};
useEffect(() => {
fetchUsers();
}, []);
return (
<div>
<h1>User List</h1>
<ul>
{users.map((user) => (
<li key={user.id}>{user.name}</li>
))}
</ul>
</div>
);
}Code language: JavaScript (javascript)依存関係が変更されるたびにエフェクトを実行する
特定の値が変更されたときに関数を実行するには、それらの値をdependencies配列に指定できます。
次のCounterTitleコンポーネントは、useEffect()フックを利用して、count状態変数が変更されたときにドキュメントのタイトルを更新します。
import { useState, useEffect } from 'react';
const CounterTitle = () => {
const [count, setCount] = useState(0);
useEffect(() => {
document.title = `Count: ${count}`;
}, [count]);
return (
<div>
<h1>Current count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default CounterTitle;Code language: JavaScript (javascript)再レンダリングのたびにエフェクトを実行する
初回レンダリング時と再レンダリングのたびに関数を実行するには、useEffect()関数にsetup関数のみを渡し、dependencies配列を省略します。
たとえば、コンポーネントがレンダリングされるとき、および再レンダリングされるたびにメッセージをログに記録できます。
import React, { useState, useEffect } from 'react';
const Counter = () => {
const [count, setCount] = useState(0);
useEffect(() => {
console.log('Component rendered or rerendered');
});
return (
<div>
<h1>Current count: {count}</h1>
<button onClick={() => setCount(count + 1)}>Increment</button>
</div>
);
};
export default Counter;Code language: JavaScript (javascript)クリーンアップ関数を実行する
次のWindowDimensionコンポーネントは、ウィンドウのリサイズイベントをリッスンし、ウィンドウのサイズに基づいて幅と高さの状態変数を更新します。
import { useState, useEffect } from 'react';
function WindowDimension() {
const [width, setWidth] = useState(window.innerWidth);
const [height, setHeight] = useState(window.innerHeight);
useEffect(() => {
// Define the handler function that updates the state with the window's width
const handleResize = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
};
// Add the event listener for window resize
window.addEventListener('resize', handleResize);
// Cleanup function: Remove the event listener when the component unmounts
return () => {
window.removeEventListener('resize', handleResize);
};
}, []);
return (
<div>
<p>
Current dimension: {width}x{height}px
</p>
</div>
);
}
export default WindowDimension;Code language: JavaScript (javascript)どのように機能するか
まず、ウィンドウのinnerWidthとinnerHeightに基づいて幅と高さの状態変数を更新するhandleResize()関数を定義します。
const handleResize = () => {
setWidth(window.innerWidth);
setHeight(window.innerHeight);
};Code language: JavaScript (javascript)次に、handleResize()関数を使用して、リサイズイベントのイベントリスナーを登録します。
window.addEventListener('resize', handleResize);Code language: JavaScript (javascript)3番目に、useEffectからクリーンアップ関数を返し、window.removeEventListenerメソッドを使用してリサイズイベントリスナーを削除します。
return () => {
window.removeEventListener('resize', handleResize);
};Code language: JavaScript (javascript)これにより、コンポーネントがDOMから削除された後にhandleResize関数が呼び出されるのを防ぎ、メモリリークや望ましくない動作につながるのを防ぎます。
まとめ
- コンポーネントがレンダリングおよび再レンダリングされるときに
setup関数を実行するには、useEffect(setup)を使用します。 - 初回レンダリング時に一度だけ
setup関数を実行するには、useEffect(setup,[])を使用します。 - コンポーネントがレンダリングされ、
dependencies配列内の項目が変更されるたびにsetup関数を実行するには、useEffect(setup, [dependencies])を使用します。