useEffect() クリーンアップ解説
React Hooks の useEffect() で componentWillUnmount に相当するクリーンアップ処理
React Hooks の useEffect()
は、コンポーネントのレンダリング後に副作用を実行する機能を提供します。この副作用は、コンポーネントがアンマウントされる前にクリーンアップされる必要があります。これは、従来のクラスコンポーネントの componentWillUnmount
ライフサイクルメソッドに相当します。
useEffect() の第2引数に依存配列を指定することで、クリーンアップ処理のタイミングを制御することができます。依存配列が変更された場合のみクリーンアップ処理が実行されます。
依存配列の指定によるクリーンアップタイミングの制御
`` import { useEffect, useState } from 'react';
function MyComponent() { const [count, setCount] = useState(0); const [effectCount, setEffectCount] = useState(0);
useEffect(() => { const intervalId = setInterval(() => { setCount(count + 1); }, 1000);
// クリーンアップ処理: インターバルをクリアする
return () => {
clearInterval(intervalId);
};
}, [effectCount]);
return ( <div> <p>Count: {count}</p> <button onClick={() => setEffectCount(effectCount + 1)}>Update Effect</button> </div> ); } ``
- 依存配列に
effectCount
を指定しているため、effectCount
が変更されない限りクリーンアップ処理は実行されません。 - クリーンアップ処理として、
setInterval()
で取得したintervalId
を使ってインターバルをクリアします。 - コールバックの中で、
setInterval()
を使って1秒ごとにcount
を更新するインターバルを設定しています。 effectCount
が変更されるたびに、useEffect()
のコールバックが実行されます。- この例では、
useEffect()
の依存配列にeffectCount
を指定しています。
依存配列の空配列指定による componentWillUnmount
に相当するクリーンアップ
依存配列を空配列 []
に指定すると、useEffect()
のコールバックはコンポーネントのマウント時とアンマウント時のみに実行されます。つまり、従来のクラスコンポーネントの componentWillUnmount
に相当するクリーンアップ処理を実装できます。
`` useEffect(() => { // マウント時に実行される処理 console.log('Component mounted');
return () => { // アンマウント時に実行されるクリーンアップ処理 console.log('Component unmounted'); }; }, []); ``
この例では、useEffect()
の依存配列が空配列なので、コールバックはコンポーネントのマウント時に一度だけ実行されます。また、コールバックの返り値であるクリーンアップ関数は、コンポーネントがアンマウントされる際に実行されます。
重要ポイント
- 依存配列には参照型(オブジェクトや配列)が含まれている場合、依存配列の内容が変更されるとクリーンアップ処理が実行される可能性があります。注意が必要です。
- 依存配列の要素を変更すると、
useEffect()
のコールバックが再実行されます。 - 空配列を指定すると、従来の
componentWillUnmount
に相当するクリーンアップ処理を実装できます。 - 依存配列を適切に指定することで、クリーンアップ処理のタイミングを制御できます。
import { useEffect, useState } from 'react';
function MyComponent() {
const [count, setCount] = useState(0);
const [effectCount, setEffectCount] = useState(0);
useEffect(() => {
const intervalId = setInterval(() => {
setCount(count + 1);
}, 1000);
// クリーンアップ処理: インターバルをクリアする
return () => {
clearInterval(intervalId);
};
}, [effectCount]);
return (
<div>
<p>Count: {count}</p>
<button onClick={() => setEffectCount(effectCount + 1)}>Update Effect</button>
</div>
);
}
useEffect(() => {
// マウント時に実行される処理
console.log('Component mounted');
return () => {
// アンマウント時に実行されるクリーンアップ処理
console.log('Component unmounted');
};
}, []);
useEffect(() => {
// マウント時に実行される処理
console.log('Component mounted');
return () => {
// アンマウント時に実行されるクリーンアップ処理
console.log('Component unmounted');
};
}, []);
useLayoutEffect()
の使用
useLayoutEffect()
は、useEffect()
と似ていますが、ブラウザのレイアウトフェーズの後に実行されます。そのため、DOMの変更が完了してからクリーンアップ処理を実行したい場合に適しています。
useLayoutEffect(() => {
// DOMの変更が完了してから実行される処理
console.log('DOM changes completed');
return () => {
// アンマウント時に実行されるクリーンアップ処理
console.log('Component unmounted');
};
}, []);
カスタムフックの使用
複雑なクリーンアップ処理が必要な場合は、カスタムフックを作成して共通化することができます。
function useUnmountEffect(callback) {
useEffect(() => {
return () => {
callback();
};
}, []);
}
function MyComponent() {
useUnmountEffect(() => {
console.log('Component unmounted');
});
// ...
}
他のライフサイクルメソッドの代替
特定のライフサイクルメソッドの機能が必要な場合は、useEffect()
と他のライフサイクルメソッドを組み合わせて実現することもできます。例えば、componentDidMount
の代わりに、useEffect()
の依存配列を空配列に指定してマウント時にのみ実行する処理を実装できます。
注意
- 他のライフサイクルメソッドの機能が必要な場合は、
useEffect()
と他のライフサイクルメソッドを組み合わせて実現できます。 - カスタムフックを使用することで、クリーンアップ処理を共通化することができます。
useLayoutEffect()
は、DOMの変更が完了してからクリーンアップ処理を実行したい場合に適しています。
reactjs react-hooks