React 服务端状态管理:用 TanStack Query 接管数据请求、缓存与重试
test12026-09-204 次阅读
把“服务端状态”从组件里剥离出来
组件里的状态分两类:UI 状态(弹窗开关、选中项)和服务端状态(接口数据、加载态、缓存)。后者天然带有异步、过期、重试、共享等复杂度,不该用 useState 自己硬扛。TanStack Query 专门接管这一层,你只声明“要什么数据”,它负责缓存、后台刷新、失败重试和跨组件共享。
用 useQuery 拉取并缓存数据
queryKey 是缓存的身份证,相同 key 的请求会复用同一份结果。staleTime 控制多久之内算“新鲜”,window focus 不触发刷新可以避免切回页面就闪一下。
import { useQuery, QueryClient, QueryClientProvider } from "@tanstack/react-query";
const queryClient = new QueryClient({
defaultOptions: {
queries: {
staleTime: 30_000,
retry: 2,
refetchOnWindowFocus: false,
},
},
});
async function fetchUser(id: string): Promise<{ id: string; name: string }> {
const res = await fetch(`/api/users/${id}`);
if (!res.ok) throw new Error(`请求失败: ${res.status}`);
return res.json();
}
function UserCard({ id }: { id: string }) {
const { data, isLoading, isError, error } = useQuery({
queryKey: ["user", id],
queryFn: () => fetchUser(id),
});
if (isLoading) return <p>加载中…</p>;
if (isError) return <p>出错:{(error as Error).message}</p>;
return <p>{data?.name}</p>;
}
export function App() {
return (
<QueryClientProvider client={queryClient}>
<UserCard id="1" />
</QueryClientProvider>
);
}
用 useMutation 写数据并联动缓存
写操作走 useMutation。关键在于 onSuccess 里调用 invalidateQueries,让相关列表缓存失效并自动重新拉取,避免手动维护数组。
import { useMutation, useQueryClient } from "@tanstack/react-query";
async function createPost(body: { title: string }) {
const res = await fetch("/api/posts", {
method: "POST",
headers: { "Content-Type": "application/json" },
body: JSON.stringify(body),
});
if (!res.ok) throw new Error("创建失败");
return res.json();
}
function NewPostForm() {
const qc = useQueryClient();
const mutation = useMutation({
mutationFn: createPost,
onSuccess: () => {
qc.invalidateQueries({ queryKey: ["posts"] });
},
});
return (
<button onClick={() => mutation.mutate({ title: "新文章" })}>
{mutation.isPending ? "提交中" : "发布"}
</button>
);
}
工程收益
- 组件不再持有 loading/error/数据的零散 useState,逻辑收敛到 hook。
- 相同 queryKey 的多个组件共享一份请求与缓存,天然去重。
- retry 与 staleTime 集中配置,重试策略不再散落各处。
T
test1
文章作者
把“服务端状态”从组件里剥离出来 组件里的状态分两类:UI 状态(弹窗开关、选中项)和服务端状态(接口数据、加载态、缓...
- 分类
- 技术
- 发布时间
- 2026-09-20
- 字数
- 约 2285 字
- 阅读
- 4 次
