ReactJS useEffect: 空の依存関係配列と依存関係配列なしの違い
ReactJSのuseEffectにおける空の依存関係配列と依存関係配列なしの違い
useEffectは2つの引数を受け取ります。
- 1つ目は、実行したい処理を記述した関数です。
- 2つ目は、依存関係の配列です。
依存関係の配列は、useEffectがいつ実行されるかを決定します。
空の依存関係配列と依存関係配列なしは、useEffectの動作に異なる影響を与えます。
空の依存関係配列
useEffectに空の依存関係配列を渡すと、コンポーネントがマウントされるか更新されるたびに実行されます。
これは、以下の場合に役立ちます。
- コンポーネントがマウントされた時に、一度だけ実行したい処理がある
例:
const MyComponent = () => {
useEffect(() => {
// コンポーネントがマウントされた時に、一度だけ実行される処理
console.log('useEffectが実行されました');
}, []);
return (
<div>
<h1>MyComponent</h1>
</div>
);
};
この例では、useEffectはコンポーネントがマウントされた時に一度だけconsole.log('useEffectが実行されました')
を実行します。
依存関係配列なし
useEffectに依存関係配列を渡さない場合は、コンポーネントがマウントされるか更新されるたびに**、そして****依存関係の値が変化するたびに実行されます。
- コンポーネントが更新されるたびに、依存関係の値に基づいて処理を実行したい
const MyComponent = () => {
const [count, setCount] = useState(0);
useEffect(() => {
// countの値が変化するたびに実行される処理
console.log(`countが${count}に変化しました`);
}, [count]);
return (
<div>
<h1>MyComponent</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
};
この例では、useEffectはcount
の値が変化するたびにconsole.log(
countが${count}に変化しました)
を実行します。
useEffectの動作を理解することで、副作用を適切に処理することができます。
const MyComponent = () => {
const [count, setCount] = useState(0);
// 空の依存関係配列
useEffect(() => {
// コンポーネントがマウントされるか更新されるたびに実行される処理
console.log('useEffect(空の依存関係配列)が実行されました');
}, []);
// 依存関係配列なし
useEffect(() => {
// コンポーネントがマウントされるか更新されるたびに、
// そしてcountの値が変化するたびに実行される処理
console.log(`useEffect(依存関係配列なし) countが${count}に変化しました`);
});
// 依存関係配列
useEffect(() => {
// countの値が変化するたびに実行される処理
console.log(`useEffect(依存関係配列) countが${count}に変化しました`);
}, [count]);
return (
<div>
<h1>MyComponent</h1>
<p>Count: {count}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
};
useEffect(空の依存関係配列)が実行されました
useEffect(依存関係配列なし) countが0に変化しました
useEffect(依存関係配列) countが0に変化しました
countが1に変化しました
useEffect(依存関係配列なし) countが1に変化しました
useEffect(依存関係配列) countが1に変化しました
解説
useEffect(依存関係配列)
は、count
の値が変化するたびに実行されます。
useEffectのその他の方法
useRefは、コンポーネントのレンダリング間で値を保持するために使用できます。これは、副作用を実行するタイミングを制御するために使用できます。
const MyComponent = () => {
const countRef = useRef(0);
useEffect(() => {
// コンポーネントがマウントされた時に一度だけ実行される処理
console.log('useEffectが実行されました');
}, []);
const handleClick = () => {
// countRef.currentは、レンダリング間で保持されます
countRef.current++;
console.log(`countが${countRef.current}に変化しました`);
};
return (
<div>
<h1>MyComponent</h1>
<p>Count: {countRef.current}</p>
<button onClick={handleClick}>+</button>
</div>
);
};
この例では、countRef
を使用して、count
の値をレンダリング間で保持しています。handleClick
関数は、countRef.current
を増やして、現在のcount
の値を出力します。
useMemoは、値を計算してキャッシュするために使用できます。これは、高価な計算を回避するために使用できます。
const MyComponent = () => {
const [count, setCount] = useState(0);
// 高価な計算
const expensiveCalculation = () => {
console.log('高価な計算を実行しています');
return count * 2;
};
// useMemoを使用して、expensiveCalculationの結果をキャッシュ
const result = useMemo(expensiveCalculation, [count]);
return (
<div>
<h1>MyComponent</h1>
<p>Count: {count}</p>
<p>Result: {result}</p>
<button onClick={() => setCount(count + 1)}>+</button>
</div>
);
};
この例では、useMemo
を使用して、expensiveCalculation
の計算結果をキャッシュしています。count
の値が変化した場合のみ、expensiveCalculation
は再実行されます。
useReducerは、状態管理のためのカスタムロジックを実装するために使用できます。これは、複雑な副作用を処理するために使用できます。
const MyComponent = () => {
const [state, dispatch] = useReducer(reducer, initialState);
useEffect(() => {
// コンポーネントがマウントされた時に一度だけ実行される処理
console.log('useEffectが実行されました');
}, []);
const handleClick = () => {
// dispatchを使用して、状態を更新
dispatch({ type: 'INCREMENT' });
};
return (
<div>
<h1>MyComponent</h1>
<p>Count: {state.count}</p>
<button onClick={handleClick}>+</button>
</div>
);
};
const reducer = (state, action) => {
switch (action.type) {
case 'INCREMENT':
return { ...state, count: state.count + 1 };
default:
return state;
}
};
const initialState = {
count: 0,
};
この例では、useReducer
を使用して、count
の状態を管理しています。dispatch
を使用して、状態を更新することができます。
useEffectは、Reactコンポーネント内で副作用を実行するための便利なフックです。ただし、他の方法も存在します。状況に応じて、最適な方法を選択する必要があります。
reactjs react-hooks use-effect