Skip to content

Latest commit

 

History

History
199 lines (144 loc) · 8 KB

cache.ja.mdx

File metadata and controls

199 lines (144 loc) · 8 KB

import { Callout } from 'nextra-theme-docs'

Cache

この機能を使用するには、最新のバージョン( ≥ 1.0.0 )にアップグレードしてください。 ほとんどの場合、キャッシュを直接変更しないでください。予期しない動作が発生する可能性があります。キーを手動で変更する必要がある場合は、 SWR API の使用を検討してください。
参照:[ミューテーション](/docs/mutation), [テストケース間のキャッシュのリセット](#テストケース間のキャッシュのリセット)

デフォルトでは、 SWR はグローバルキャッシュを使用して、すべてのコンポーネント間でデータを保存および共有します。ただし、 SWRConfigprovider オプションを使用して、その挙動をカスタマイズできます。

キャッシュプロバイダーは、よりカスタマイズされたストレージで SWR を実現することを目的としています。

キャッシュプロバイダー

キャッシュプロバイダーは、次の TypeScript 定義( swr からインポート可能 )に一致する Map のようなオブジェクトです:

interface Cache<Data> {
  get(key: string): Data | undefined
  set(key: string, value: Data): void
  delete(key: string): void
}

たとえば、JavaScript Map インスタンスを SWR のキャッシュプロバイダーとして直接使用できます。

キャッシュプロバイダーの作成

SWRConfigprovider オプションは、 キャッシュプロバイダーを返す関数を受け取ります。受け取ったプロバイダーは、その SWRConfig の範囲内のすべての SWR フックで使用されます。例:

import useSWR, { SWRConfig } from 'swr'

function App() {
  return (
    <SWRConfig value={{ provider: () => new Map() }}>
      <Page/>
    </SWRConfig>
  )
}

<Page /> 内のすべての SWR フックは、その Map インスタンスから読み取りと書き込みを行います。また、特定のユースケースに合わせて、他のキャッシュプロバイダーの実装を使用することもできます。

上記の例では、 `` コンポーネントが再マウントされると、プロバイダーも再生成します。キャッシュプロバイダーは、コンポーネントツリーの上位、またはレンダリングの外部に配置する必要があります。

import { Cache } from '@components/diagrams/cache'

ネストされている場合、 SWR フックは上位レベルのキャッシュプロバイダーを使用します。もし上位レベルのキャッシュプロバイダーが無い場合は、空の Map をデフォルトのキャッシュプロバイダーとして使用します。

キャッシュプロバイダーを使用している場合、グローバルな `mutate` は `` 以下の SWR フックでは**機能しません**。代わりに [こちら](#現在のキャッシュプロバイダーにアクセスする) を使用してください。

現在のキャッシュプロバイダーにアクセスする

React コンポーネント内では、 mutate を含む他の設定と同様に、現在のキャッシュプロバイダーへアクセスするために、 useSWRConfig フックを使用する必要があります。

import { useSWRConfig } from 'swr'

function Avatar() {
  const { cache, mutate, ...extraConfig } = useSWRConfig()
  // ...
}

<SWRConfig> 以下でない場合は、デフォルトの設定を返します。

実験的:キャッシュプロバイダーの拡張

これは実験的な機能であり、将来のアップグレードで動作が変更される可能性があります。

複数の <SWRConfig> コンポーネントがネストされている場合、キャッシュプロバイダーを拡張できます。

provider の最初の引数は、上位レベルの <SWRConfig> のキャッシュプロバイダー( 親が <SWRConfig> でない場合はデフォルトのキャッシュ )です。これを使用して、キャッシュプロバイダーを拡張できます:

<SWRConfig value={{ provider: (cache) => newCache }}>
  ...
</SWRConfig>

正規表現から複数のキーを変更する

キャッシュプロバイダー API の柔軟性により、"部分的な変更"のヘルパーを構築することもできます。

以下の例では、 matchMutate はキーとして正規表現を受け取り、パターンに一致するものを変更するために使用できます。

function useMatchMutate() {
  const { cache, mutate } = useSWRConfig()
  return (matcher, ...args) => {
    if (!(cache instanceof Map)) {
      throw new Error('matchMutate requires the cache provider to be a Map instance')
    }

    const keys = []

    for (const key of cache.keys()) {
      if (matcher.test(key)) {
        keys.push(key)
      }
    }

    const mutations = keys.map((key) => mutate(key, ...args))
    return Promise.all(mutations)
  }
}

次に、コンポーネントの内部:

function Button() {
  const matchMutate = useMatchMutate()
  return <button onClick={() => matchMutate(/^\/api\//)}>
    Revalidate all keys start with "/api/"
  </button>
}
この例では、キャッシュプロバイダーが Map インスタンスである必要があることに注意してください。

LocalStorage を使った永続キャッシュ

キャッシュを localStorage で同期しても良いかもしれません。実装例は次の通りです:

function localStorageProvider() {
  // 初期化時に、 `localStorage` から Map にデータを復元します。
  const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]'))

  // アプリが終了する前に、すべてのデータを `localStorage` に保存します。
  window.addEventListener('beforeunload', () => {
    const appCache = JSON.stringify(Array.from(map.entries()))
    localStorage.setItem('app-cache', appCache)
  })

  // パフォーマンスのために、書き込みと読み取りには引き続き Map を使用します。
  return map
}

次に、プロバイダーとして使用します:

<SWRConfig value={{ provider: localStorageProvider }}>
  <App/>
</SWRConfig>
改善点として、メモリキャッシュをバッファとして使用し、定期的に `localStorage` に書き込むこともできます。 IndexedDB または WebSQL を使用して同様の階層化キャッシュを実装することもできます。

テストケース間のキャッシュのリセット

アプリケーションをテストするときは、テストケース間で SWR キャッシュをリセットすることをオススメします。空のキャシュプロバイダーでアプリケーションをラップするだけです。 Jest の例を次に示します:

describe('test suite', async () => {
  it('test case', async () => {
    render(
      <SWRConfig value={{ provider: () => new Map() }}>
        <App/>
      </SWRConfig>
    )
  })
})

キャッシュへアクセスする

警告:キャッシュに直接書き込むことはするべきではありません。予期しない動作が発生する可能性があります。

const { cache } = useSWRConfig()

cache.get(key) // キーの現在のデータを取得します。
cache.clear()  // ⚠️ すべてのキャッシュをクリアします。 SWRは、再レンダリング時に再検証します。