0Pricing
React Academy · レッスン

useMemoによるContext値のメモ化

Contextの値オブジェクトをuseMemoでラップし、不要な再レンダーを防ぎます。

「useMemoによるContext値のメモ化」はCoddyKit上の無料React Academyレッスンです。 これはレッスン2/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはReact Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 React Academyコースには全4レッスンが含まれています。

ようこそ

このレッスンでは、コンテキスト値のオブジェクトを useMemo でメモ化する必要がある理由と、不要な再レンダリングを避けるための依存関係の正しい設定方法を学びます。

オブジェクト参照の問題

Provider コンポーネントが再レンダリングされるたびに、内容が同じでも新しいオブジェクトリテラル `{ ... }` がコンテキスト値として作成されます。参照が変化するため、すべてのコンシューマーが再レンダリングされます。
// Every render creates a new object!
<UserCtx.Provider value={{ user, logout }}>
  {children}
</UserCtx.Provider>

useMemo による解決

コンテキスト値を useMemo でラップします。deps 配列内の値に変化がなければ、レンダリング間で同じオブジェクト参照が返されます。
const value = useMemo(
  () => ({ user, logout }),
  [user, logout]
);

<UserCtx.Provider value={value}>
  {children}
</UserCtx.Provider>

依存関係の慎重な選択

useMemo 内で使用するすべての値を deps 配列に含めます。依存関係が不足すると、古い値が使われます。プリミティブな props(文字列や数値)と、useCallback でラップした関数などの安定した参照を含めます。

useCallback による関数の安定化

関数の値はレンダリングのたびに参照が変化します。不要な再レンダリングを防ぐには、useMemo のコンテキスト値に含める前に useCallback でラップします。
const logout = useCallback(() => {
  clearSession();
  setUser(null);
}, []);

const value = useMemo(() => ({ user, logout }), [user, logout]);

メモ化が不要な場合

Provider コンポーネントが再レンダリングされない場合(たとえばツリーの最上部にあり、親が変化しない場合)、useMemo はメリットがなくオーバーヘッドだけを加えます。Provider 自体が再レンダリングされる場合にだけメモ化してください。

プリミティブ値はすでに安定している

コンテキスト値がプリミティブ(文字列、数値、真偽値)の場合、useMemo は必要ありません。プリミティブは参照ではなく値で比較されます。`value={isDark}` によって余分な再レンダリングが発生することはありません。
// No useMemo needed for primitives
<ThemeCtx.Provider value={isDark ? 'dark' : 'light'}>
  {children}
</ThemeCtx.Provider>

メモ化の効果のプロファイリング

React DevTools Profiler を使って、コンテキスト値を useMemo でラップすることで実際に再レンダリングが減少するか確認します。前後のセッションを記録し、コミット数の違いを比較します。

ネストしたメモ化コンテキスト

複数のコンテキストをネストする場合は、それぞれを個別にメモ化します。1 つのコンテキストの変更が、別のコンテキストのメモ化された値に影響することはありません。

Provider コンポーネントパターン

コンテキスト、state、メモ化を専用の Provider コンポーネント内にカプセル化します。コンテキストを使用するためのカスタムフックを export します。これは、再利用可能なコンテキストで使われる標準的なパターンです。
export function UserProvider({ children }) {
  const [user, setUser] = useState(null);
  const logout = useCallback(() => setUser(null), []);
  const value = useMemo(() => ({ user, logout }), [user, logout]);
  return <UserCtx.Provider value={value}>{children}</UserCtx.Provider>;
}

export const useUser = () => useContext(UserCtx);

理解度チェック

コンテキスト値のオブジェクトを useMemo でラップする主な理由は何でしょうか?

まとめ

コンテキスト値のオブジェクトを、正しい deps とともに useMemo でラップします。useCallback で関数の値を安定させます。プリミティブにはメモ化は必要ありません。コンテキストの設定を、カスタムフックを備えた Provider コンポーネントにカプセル化します。

次のレッスン

次のレッスンは **Context Selector Pattern** です。特定のコンテキストの一部分が変化した場合にだけコンシューマーを再レンダリングする selector hook を実装します。

よくある質問

「useMemoによるContext値のメモ化」レッスンは無料ですか?

はい。「useMemoによるContext値のメモ化」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、React Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 React Academyコースには全4レッスンが含まれています。

「useMemoによるContext値のメモ化」で何を学びますか?

Contextの値オブジェクトをuseMemoでラップし、不要な再レンダーを防ぎます。 ブラウザで直接実行するハンズオンコードでReact Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

React Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのReact Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン2/4です。

「useMemoによるContext値のメモ化」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このReact Academyレッスンでコードを書いて実行できますか?

はい。すべてのReact Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. 再レンダーを抑えるためのContext分割
  2. useMemoによるContext値のメモ化
  3. Context Selectorパターン
  4. Contextを使わないケース
← React Academyに戻る