useEffectフックを使って、コンポーネントがアンマウントされるときにクリーンアップ処理を実行することは一般的です。しかし、クリーンアップ処理がコンポーネントのライフタイム中に変更される場合、問題が生じる可能性があります。
以下のようなコードでは、コールバック関数がコンポーネントがマウントされたときのものしか呼び出されません。
変更された場合、変更後のコールバック関数は呼び出されません。
const callback = console.log('Component is unmounting. Clean up:', props.cleanupTarget);
React.useEffect(() => {
return () => {
callback();
}
},
// アンマウント時のみ実行するために空配列にする
[]);
この問題を解決するために、useRefフックを使って最新のコールバック関数を記憶します。そして、useEffectのクリーンアップ関数でそのコールバック関数を呼び出します。
const callbackRef = React.useRef<() => void>();
const callback = console.log('Component is unmounting. Clean up:', props.cleanupTarget);
React.useEffect(() => {
callbackRef.current = callback;
}, [callback]);
React.useEffect(() => {
return () => {
if (callbackRef.current) {
callbackRef.current();
callbackRec.current = undefined;
}
};
}, []);
この例では、useRefフックを使って最新のコールバック関数を記憶しておき、useEffectのクリーンアップ関数でそのコールバック関数を呼び出しています。これにより、コールバック関数が変更された場合でも、常に最新のコールバック関数がコンポーネントのアンマウント時に呼び出されます。