-
useMemo
: 計算結果をメモ化するために使用。重い計算を最適化。 -
React.memo
: コンポーネントのレンダリングを最適化。propsが変わらない限り再レンダリングを防ぐ。 -
useCallback
: 関数をメモ化するために使用。依存配列の変更がない限り、同じ関数参照を再利用。
1. useMemo
useMemo
は、計算コストの高い値をメモ化するために使用されます。依存配列に指定した値が変更されない限り、前回の計算結果を再利用します。
import React, { useMemo, useState } from 'react';
const ExpensiveComponent = ({ num }) => {
const expensiveValue = useMemo(() => {
console.log('計算中...');
return num * 2; // 高コストな計算
}, [num]);
return <div>計算結果: {expensiveValue}</div>;
};
const App = () => {
const [count, setCount] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>カウント: {count}</button>
<ExpensiveComponent num={count} />
</div>
);
};
2. React.memo
React.memo
は、コンポーネントのレンダリングを最適化するために使用されます。親コンポーネントが再レンダリングされても、propsが変更されない限り、子コンポーネントは再レンダリングされません。
import React, { useState } from 'react';
const ChildComponent = React.memo(({ count }) => {
console.log('ChildComponentがレンダリングされました');
return <div>カウント: {count}</div>;
});
const App = () => {
const [count, setCount] = useState(0);
const [otherState, setOtherState] = useState(0);
return (
<div>
<button onClick={() => setCount(count + 1)}>カウント: {count}</button>
<button onClick={() => setOtherState(otherState + 1)}>他の状態: {otherState}</button>
<ChildComponent count={count} />
</div>
);
};
3. useCallback
useCallback
は、関数をメモ化するために使用されます。依存配列に指定した値が変更されない限り、前回の関数を再利用します。これにより、子コンポーネントに渡す関数が毎回新しい参照を持つことを防ぎ、不要な再レンダリングを避けることができます。
import React, { useCallback, useState } from 'react';
const Button = React.memo(({ onClick }) => {
console.log('Buttonがレンダリングされました');
return <button onClick={onClick}>クリック</button>;
});
const App = () => {
const [count, setCount] = useState(0);
const handleClick = useCallback(() => {
setCount(count + 1);
}, [count]);
return (
<div>
<Button onClick={handleClick} />
<div>カウント: {count}</div>
</div>
);
};
4. useMemo
とuseCallback
の似たような実装の例
例えば、数値を2倍にする関数をメモ化する場合、useMemo
とuseCallback
の両方を使って実現することができます。
useMemo
を使用した場合
import React, { useMemo, useState } from 'react';
const App = () => {
const [num, setNum] = useState(0);
const doubledValue = useMemo(() => {
console.log('計算中...');
return num * 2; // 高コストな計算
}, [num]);
return (
<div>
<button onClick={() => setNum(num + 1)}>数を増やす: {num}</button>
<div>2倍: {doubledValue}</div>
</div>
);
};
useCallback
を使用した場合
import React, { useCallback, useState } from 'react';
const App = () => {
const [num, setNum] = useState(0);
const double = useCallback(() => {
console.log('計算中...');
return num * 2; // 高コストな計算
}, [num]);
const doubledValue = double();
return (
<div>
<button onClick={() => setNum(num + 1)}>数を増やす: {num}</button>
<div>2倍: {doubledValue}</div>
</div>
);
};
違いのポイント
-
目的:
-
useMemo
: 計算結果をメモ化して、再計算を避けるために使用します。 -
useCallback
: 関数の参照をメモ化して、子コンポーネントの不必要な再レンダリングを防ぐために使用します。
-
-
戻り値の性質:
-
useMemo
は、計算結果を返します。 -
useCallback
は、関数自体を返します。
-
-
使用シーン:
-
useMemo
は、重い計算や複雑なオブジェクトの生成などに使います。 -
useCallback
は、特に子コンポーネントに関数を渡す場合に重要です。
-
特徴 | useMemo |
useCallback |
---|---|---|
目的 | 計算結果のメモ化 | 関数のメモ化 |
戻り値 | メモ化された値 | メモ化された関数 |
使用シーン | 重い計算を行う場合に使用 | 子コンポーネントに関数を渡す場合に使用 |
依存配列 | 依存する値が変更されると再計算 | 依存する値が変更されると新しい関数を生成 |