loneProgrammer

Request Memoization(リクエストメモリゼーション):Import Cache From React

「import { cache } from ‘react’」は Request Memoization に関連する機能です。

概要

  • 基本的な実装例
  • import { cache } from 'react'
    import db from '@/lib/db'
    export const getItem = cache(async (id: string) => {
     const item = await db.item.findUnique({ id })
     return item
    })

位置付け

Request Memoization に関連する機能です

主な特徴

  • 関数の戻り値をメモ化(キャッシュ)
  • 同一引数での複数回の呼び出しは1回の実行のみ
  • リクエストのライフサイクル中のみ有効
  • レンダリング完了時に自動クリア

使用ケース

  • fetchが使用できない場合
  • データベースクライアント
  • CMSクライアント
  • GraphQLクライアント
  • その他
  • 複数コンポーネントでの同一データ使用時

注意点

  • NextJsのfetchは、自動メモ化されるためcache不要
  • cache関数は、サーバーサイドのみで機能
  • リクエスト間で、キャッシュが保持されるわけではない

使用例

  • async function Page() {
     // 同じidで複数回呼び出しても、DBクエリは1回だけ
     const item1 = await getItem('123')
     const item2 = await getItem('123') // キャッシュから取得
     return(
      <h1>{item2.title}</h1>
     )
    }
    export async function generateMetadata(): Promise<Metadata> {
     const item3 = await getItem('123') // キャッシュから取得
     return {
      title:item3.title,
      --省略--
     }
    }

Note: この機能は、パフォーマンス最適化とサーバーリソースの効率的な使用のために設計されています。

使用例(注意)

  • オブジェクト形式の引数を使用する場合の注意点
  • ❌ キャッシュされない例
  • export const getItemA = cache(({
     search,
    }:{
     search:string
    }) => {
     return search;
    })
    // 毎回新しいオブジェクトが生成されるため、キャッシュが効かない
    const result1 = await getItemA({ search: "test" })  // 実行される
    const result2 = await getItemA({ search: "test" })  // また実行される
  • ✅ キャッシュされる例(参照を統一)
  • // 同じオブジェクトを使用することでキャッシュが有効になる
    const searchParams = { search: "test" };
    const result1 = await getItemA(searchParams)  // 実行される
    const result2 = await getItemA(searchParams)  // キャッシュから取得
  • ✅ キャッシュされる例(個別パラメータ)
  • export const getItemB = cache((search:string) => {
     return search;
    })
    // プリミティブ値を直接渡すため、キャッシュが効く
    const result1 = await getItemB("test")  // 実行される
    const result2 = await getItemB("test")  // キャッシュから取得

重要: オブジェクト形式の引数を使用する場合は、必ず参照を統一するか、個別のパラメータとして設定することをお勧めします。

↓ お勧め記事 ↓