← Hooked.
useMemo
公式ドキュメント ↗const primeCount = useMemo(() => countPrimesUpTo(n), [n]);
// nが変わらない限り、countPrimesUpTo自体を呼び直さない「同じ中身」でも「別物」として扱われる
const config = useMemo(() => ({ label: "x" }), []); // 参照が安定する
<MemoChild config={config} />;子はReact.memoでラップ済み。両方とも「親を描き直す」を押すと、左は子も毎回描き直され、右は初回のまま変わらない。オブジェクトや配列は描き直すたびに新しく作り直される(中身が同じでも、JavaScriptの世界では別物として扱われる)。React.memoでラップした子に渡す場合、useMemoで同じ参照を使い回さないとmemoが効かず、毎回描き直されてしまう。
今の時代の使いどころ: React Compilerとの関係
このHooked.自体もReact Compiler(next.config.tsのreactCompiler: true)を有効にして動いている。React Compilerは、コンパイル時にコンポーネントを解析して、上のようなuseMemo/React.memoが本来やっていた最適化の多くを自動的にやってくれる。つまり普段書くコードでは、これらを手で書く場面はどんどん減っている。
// next.config.ts
const nextConfig: NextConfig = {
reactCompiler: true, // このデモ以外のHooked.内のコンポーネントは自動メモ化されている
};それでも手動のuseMemoが必要になるのは、コンパイラが安全に推論できないケース(副作用や非決定的な処理を含む計算など)や、挙動を明示的に固定したい場面。まずは素の関数として書き、必要になった時だけ最適化する、くらいの距離感がちょうどいい。