Capítulo 32 de 456
Use SWR pra buscar dado em Client Components, fornecer dado inicial a partir de Server Components via <SWRConfig fallback>, e coordenar mutations do browser com dado server cacheado através de uma cache key/tag compartilhada.
useSWR(key, fetcher, options): hook principal; key condicional (query ? url : null) atrasa a requisição até ter input.suspense: true: delega o loading state ao Suspense boundary mais próximo; revalidações subsequentes mantêm o dado atual em tela (não voltam ao fallback).isLoading vs isValidating: isLoading é true quando há requisição rodando e nenhum dado carregado; isValidating é true sempre que há requisição rodando, incluindo revalidação em background.<SWRConfig fallback>: escopar ao segmento de rota dono do dado; a key do fallback e do useSWR devem ser idênticas ou SWR ignora o fallback e busca no client.revalidateIfStale: false: pula revalidação ao montar com dado cacheado (aplica-se a cada mount, diferente do staleTime do TanStack Query).refreshInterval: revalidação por polling agendado.mutate(key, updater, options): dispara write com optimisticData, revalidate: false, rollbackOnError: true, throwOnError: false.key(id) e tag(id) usado tanto pelo fallback/useSWR (key) quanto pelo cacheTag server (tag); deve ficar livre de imports server-only/client-only.'use client'
import useSWR from 'swr'
export function ProductAutocomplete({ query }: { query: string }) {
const { data = [], error, isLoading } = useSWR(
query ? `/api/products?query=${encodeURIComponent(query)}` : null,
fetcher
)
if (!query) return null
if (error) return <p>Failed to load products.</p>
if (isLoading) return <p>Loading products...</p>
return <ul>{data.map((p) => <li key={p.id}>{p.name}</li>)}</ul>
}
export const productCache = {
key: (id: string) => `/api/products/${id}`,
tag: (id: string) => `product:${id}`,
}
'use client'
import { useSWRConfig } from 'swr'
export function MarkReadButton() {
const { mutate } = useSWRConfig()
function markRead() {
return mutate(
activityCache.key,
async () => { await markActivityReadAction(); return { count: 0 } },
{ optimisticData: { count: 0 }, revalidate: false, rollbackOnError: true, throwOnError: false }
)
}
return <button onClick={markRead}>Mark read</button>
}
updateTag.useSWR: SWR ignora o fallback silenciosamente e refaz o fetch no client. Defina a key uma única vez e importe dos dois lugares.revalidateIfStale. Não confunda com staleTime do TanStack Query.await (o componente que lê a key suspende).revalidateIfStale: false.GET que reusa a mesma função server (getProduct) usada no fallback.use cache + cacheLife + cacheTag) pra cachear o dado server que alimenta o fallback; a cache do SWR é independente e não precisa das mesmas durações.updateTag/revalidateTag no Server Action pra invalidar o read server cacheado com a mesma tag do contrato.queryKey em vez de string key).