Skip to content
Documentação
Avançado
Cache

Cache

💡

Atualize para a última versão (≥ 1.0.0) para usar este recurso.

⚠️

Na maioria dos casos, você não deve escrever diretamente no cache, o que pode causar comportamentos indefinidos do SWR. Se você precisa mutar manualmente uma chave, por favor, considere usar as APIs do SWR.
Veja também: Mutação, Redefinir Cache Entre Casos de Teste.

Por padrão, SWR usa um cache global para armazenar e compartilhar dados entre todos os componentes. Mas você pode customizar este comportamento com a opção provider do SWRConfig.

Cache Providers são destinados a permitir SWR com armazenamentos mais personalizados.

Cache Provider

Um cache provider é um objeto (parecido com um Map) que corresponde à definição de tipo TypeScript da seguinte definição (que pode ser importado de swr):

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

Por exemplo, um Map do JavaScript (opens in a new tab) pode ser usado diretamente como cache provider para SWR.

Criar Cache Provider

A opção provider do SWRConfig recebe uma função que retorna um cache provider. O provider será usado por todos os hooks SWR dentro dos limites de configuração do SWRConfig. Por exemplo:

import useSWR, { SWRConfig } from 'swr'
 
function App() {
  return (
    <SWRConfig value={{ provider: () => new Map() }}>
      <Page/>
    </SWRConfig>
  )
}

Todos os hooks SWR dentro de <Page/> lerão e escreverão naquela instância Map. Você também pode usar outras implementações de cache provider para seu caso específico.

💡

No exemplo acima, quando o componente <App/> é re-montado, o provider também é re-criado. Cache Providers devem ser colocados mais alto na árvore de componentes, ou fora do render.

Quando aninhado, hooks SWR irão usar o cache provider mais alto. Se não houver cache provider mais alto, ele irá usar o provider padrão, que é um Map vazio.

⚠️

Se um cache provider é usado, o mutate global não funcionará para os hooks SWR dentro do limite de configuração <SWRConfig>. Por favor, use isto em vez disso.

Acessar Cache Provider Atual

Quando dentro de um Componente React, você precisa usar o hook useSWRConfig para obter acesso ao cache provider atual e outras configurações, incluindo mutate:

import { useSWRConfig } from 'swr'
 
function Avatar() {
  const { cache, mutate, ...extraConfig } = useSWRConfig()
  // ...
}

Se não estiver sob nenhum <SWRConfig>, será retornado as configurações padrão.

Experimental: Estender o Cache Provider

🧪

Este é um recurso experimental, o comportamento pode mudar em futuras atualizações.

Quando vários componentes <SWRConfig> são aninhados, o cache provider pode ser estendido.

O primeiro argumento para a função provider é o cache provider do nível superior do <SWRConfig> (ou o cache padrão se não houver <SWRConfig> pai), você pode usá-lo para estender o cache provider:

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

Exemplos

Cache Persistente Baseado em LocalStorage

Você pode querer sincronizar seu cache com localStorage. Aqui está um exemplo de implementação:

function localStorageProvider() {
  // Ao inicializar, restauramos os dados de `localStorage` em um mapa.
  const map = new Map(JSON.parse(localStorage.getItem('app-cache') || '[]'))
 
  // Antes de descarregar o aplicativo, gravamos todos os dados em `localStorage`.
  window.addEventListener('beforeunload', () => {
    const appCache = JSON.stringify(Array.from(map.entries()))
    localStorage.setItem('app-cache', appCache)
  })
 
  // Ainda usamos o mapa para gravação e leitura para desempenho.
  return map
}

Em seguida, use-o como provider:

<SWRConfig value={{ provider: localStorageProvider }}>
  <App/>
</SWRConfig>
💡

Como melhoria, você também pode usar o cache de memória como um buffer e gravar em localStorage periodicamente. Você também pode implementar um cache em camadas semelhante ao IndexedDB ou WebSQL.

Redefinir Cache Entre Casos de Teste

Ao testar seu aplicativo, talvez você queira redefinir o cache SWR entre os casos de teste. Você pode simplesmente envolver seu aplicativo com um cache provider vazio. Aqui está um exemplo com Jest:

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

Modificar os Dados do Cache

const { cache } = useSWRConfig()
 
cache.get(key) // Obtém os dados atuais para uma chave.
🚨

Você não deve escrever diretamente no cache, isso pode causar um comportamento indefinido.

Você pode usar mutate para modificar o cache. Por exemplo, você pode limpar todos os dados do cache como no exemplo a seguir.

const { mutate } = useSWRConfig()
 
mutate(
  key => true, // quais chaves de cache devem ser atualizadas
  undefined, // atualiza os dados de cache para undefined
  { revalidate: false } // não revalidar os dados
)

Mais informação pode ser encontrada aqui.