概要: このチュートリアルでは、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])
を使用します。