跳到主要内容

SWR

SWR 是 React 生态里另一条很常见的数据获取路线。和 TanStack Query 相比,它通常显得更轻、更克制,尤其适合“页面取数为主,缓存和重取也要有,但不一定要把整套服务端状态系统搭满”的项目。

SWR 最常见的定位

  • React 项目
  • 页面取数
  • 缓存和重验证
  • 比较轻的数据同步需求

基本用法

import useSWR from 'swr'

const fetcher = (url: string) => fetch(url).then((res) => res.json())

function Profile() {
const { data, error, isLoading } = useSWR('/api/user', fetcher)

if (isLoading) return <div>Loading...</div>
if (error) return <div>Error</div>

return <div>{data.name}</div>
}

为什么它叫 SWR

SWR 的名字来自 stale-while-revalidate。直白一点说,就是:

  • 先用缓存数据顶上
  • 再在后台悄悄更新

这套体验对资料页、详情页、后台页面都很顺。

和请求层怎么配

和 TanStack Query 一样,SWR 也不应该直接替代请求层。

import useSWR from 'swr'
import { getUserDetail } from '@/api/user'

export function useUserDetail(id?: string) {
return useSWR(id ? ['user', id] : null, () => getUserDetail(id!))
}

常见封装方式

1. 统一 fetcher

export async function fetcher<T>(url: string) {
const res = await fetch(url)

if (!res.ok) {
throw new Error(`request failed: ${res.status}`)
}

return (await res.json()) as T
}

2. 业务 hook

export function useTodoList() {
return useSWR('/api/todos', fetcher)
}

3. 修改后主动刷新

import { mutate } from 'swr'

await createTodo(payload)
mutate('/api/todos')

SWR 和 TanStack Query 怎么看

  • SWR:更轻,React 页面对接很顺
  • TanStack Query:体系更完整,服务端状态能力更强

如果项目主要是页面取数和简单缓存,SWR 通常很舒服。只要开始碰到:

  • 大量 mutation
  • 复杂失效策略
  • 乐观更新
  • 无限列表
  • 多处共享的复杂服务端状态

TanStack Query 会更稳。