const value = useMemo(() => computeExpensiveValue(), dependencies)
const sorted = useMemo<Item[]>(
() => items.sort((a, b) => a.name.localeCompare(b.name)),
[items]
);import { useState, useMemo } from 'react';
// ── 問題: 毎レンダーで重い計算が走る ─────────────────
function WithoutMemo() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
// ❌ text が変わるたびにも重い計算が走ってしまう
const expensiveResult = heavyCalc(count);
return <div>...</div>;
}
// ✅ useMemo で計算結果をキャッシュ ───────────────────
function WithMemo() {
const [count, setCount] = useState(0);
const [text, setText] = useState('');
// count が変わったときだけ再計算。text が変わっても再計算しない
const expensiveResult = useMemo(() => {
console.log('重い計算を実行中...');
return heavyCalc(count); // 例: 素数を全部求めるなど
}, [count]); // ← count が依存配列
return (
<div>
<p>計算結果: {expensiveResult}</p>
<button onClick={() => setCount(c => c + 1)}>カウント変更</button>
<input value={text} onChange={e => setText(e.target.value)} />
{/* text を変えても重い計算は走らない */}
</div>
);
}
// ── 配列/オブジェクトの安定した参照を作るのにも使う ─
function FilteredList({ items, query }: { items: string[], query: string }) {
// query が変わったときだけフィルタリングを実行
const filtered = useMemo(
() => items.filter(item => item.includes(query)),
[items, query]
);
return <ul>{filtered.map(item => <li key={item}>{item}</li>)}</ul>;
}Reactコンパイラ(React Forget)が普及すれば useMemo を手動で書く必要はなくなる。現時点では計算コストの高い処理に限定して使う。