useMemo利用時の注意事項
React.memo
はパフォーマンス最適化のための強力なツールですが、誤用するとバグや意図しない再レンダリングの抑制が発生する可能性があります。
⚠️ 主な落とし穴と原因
1. 参照型 props による意図しない再レンダリング
<MemoizedComponent data={{ id: 1 }} />
- オブジェクトや関数は毎回新しい参照として渡されるため、
React.memo
が「変更あり」と判断して再レンダリングされる。
✅ 解決策:useMemo や useCallback で参照を固定化
const data = useMemo(() => ({ id: 1 }), [])
<MemoizedComponent data={data} />
2. props が変わっているのにレンダリングされない
const sameRef = { id: 1 }
// 中身が変わっても参照が同じなら再レンダリングされない
<MemoizedComponent data={sameRef} />
React.memo
はデフォルトで浅い比較(shallow compare)しか行わないため、中身の変更を検知できない。
✅ 解決策:カスタム比較関数を使う
const Memoized = React.memo(Component, (prevProps, nextProps) => {
return prevProps.data.id === nextProps.data.id
})
3. 副作用(useEffectなど)との相性に注意
React.memo
によって props が変わっていないと見なされると、useEffectが再実行されず副作用が動かないことがある。
4. 過剰な最適化でコードが複雑になる
memo
/useMemo
/useCallback
の多用で可読性・保守性が低下する。- 「最初から最適化しない」という原則を守ることが重要。
✅ React.memo を使うべきかどうかの判断基準
条件 | 使用推奨度 |
---|---|
propsがプリミティブ型で変更が少ない | ✅ 向いている |
propsが関数やオブジェクト | ⚠️ 要注意 |
コンポーネントの描画が重い | ✅ 有効 |
コンポーネント内部に副作用がある | ❌ 非推奨 |
パフォーマンス問題が特にない | ❌ 必要なし |
🧪 まとめ:バグを防ぐポイント
- propsが安定しているかを確認する
- useMemo / useCallback を併用する
- 必要になるまで最適化しない
- React DevToolsで挙動を観察する