React 用 SWR 做客户端数据请求:stale-while-revalidate、本地更新与焦点重验

test12026-11-011 次阅读

为什么还要看 SWR

服务端状态(接口数据)和客户端状态(表单、UI)本就是两回事。TanStack Query 功能更全,但 SWR 更轻、概念更少:它只做一件事——基于 stale-while-revalidate 策略,让缓存数据先返回、再后台刷新。下面用最小可运行的例子讲清它的三个常用能力。

基础请求与条件请求

把请求 key 设成 null,SWR 会自动暂停请求;key 变化才重新拉取。这比手写 useEffect 依赖干净得多。

import useSWR from 'swr'

const fetcher = (url: string) =>
  fetch(url).then((r) => {
    if (!r.ok) throw new Error('请求失败')
    return r.json()
  })

export function UserProfile({ id }: { id: number | null }) {
  const { data, error, isLoading } = useSWR(
    id ? `/api/users/${id}` : null,
    fetcher
  )

  if (error) return <p>加载出错</p>
  if (isLoading) return <p>加载中…</p>
  return <div>{data.name}</div>
}

本地更新:先改 UI 再同步服务端

点赞、开关这类操作,先用 mutate 把本地缓存改掉立刻反馈,再发请求,失败再回滚。这是 SWR 最有价值的一招。

const { data, mutate } = useSWR('/api/likes', fetcher)

async function like() {
  const next = { ...data, count: data.count + 1 }
  // 第二个参数 false 表示不要立刻重新请求,先展示乐观结果
  await mutate(next, { revalidate: false })
  try {
    await fetch('/api/like', { method: 'POST' })
    await mutate() // 后台再取一次真实值
  } catch {
    await mutate() // 失败则回滚到服务端真实状态
  }
}

焦点重验与全局配置

SWR 默认在窗口重新聚焦、网络恢复时自动重验,这对后台标签页和弱网很友好。用 SWRConfig 可以一次性设置全局 fetcher 和刷新策略。

import { SWRConfig } from 'swr'

function App({ children }) {
  return (
    <SWRConfig
      value={{
        fetcher,
        revalidateOnFocus: true,
        dedupingInterval: 2000,
      }}
    >
      {children}
    </SWRConfig>
  )
}

什么时候选它

  • 接口数据为主、不需要复杂的 mutations 队列:SWR 足够。
  • 包体积小、API 少、上手快:适合中型后台或快速原型。
  • 需要乐观更新、焦点重验、条件请求这些开箱即用能力:它直接给。
T

test1

文章作者

为什么还要看 SWR 服务端状态(接口数据)和客户端状态(表单、UI)本就是两回事。TanStack Query 功能...

分类
技术
发布时间
2026-11-01
字数
约 1551 字
阅读
1 次