🎙 欢迎来到《前端达人 · 播客书单》第 28 期。
视频版博客观看更精彩
今天我们正式进入数据交互领域的高效解法 —— React Query。
如果你还在用 useEffect + useState
写 API 请求逻辑、维护加载状态、写 try/catch 和 loading 错误处理的锅山代码…… 那这期内容你一定不能错过。
❓ 为什么我们需要 React Query?
传统的 React 中,发起请求的方式通常是这样的:
useEffect(() => {
setLoading(true);
fetch('/api/posts')
.then(res => res.json())
.then(data => {
setPosts(data);
})
.catch(err => setError(err))
.finally(() => setLoading(false));
}, []);
看起来没问题对吧? 但是……
要自己维护 loading 和 error 状态
要处理缓存和刷新的逻辑
页面切换回来时不会自动刷新数据
一不小心就写出“副作用地狱”
而 React Query 带来的是这样的体验:
const { data, isLoading, isError } = useQuery(['posts'], fetchPosts);
就这?对,就这!异步请求、缓存策略、错误处理、后台刷新……统统一行搞定!
🧠 React Query 是什么?
一句话定义:
一个用于 异步数据获取、缓存、同步和更新服务器状态 的 React 库。
它解决的是“远程数据状态管理”的问题,而不是本地 UI 状态。
✅ 它的优势包括:
自动缓存数据,并且感知依赖变化自动刷新
简化异步请求逻辑,减少样板代码
自动处理 loading / error 状态
支持窗口聚焦、网络重连刷新
拥有 Devtools,调试体验超爽
🧩 核心入口:QueryClientProvider
想使用 React Query,第一步是全局配置 QueryClient
:
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
const queryClient = new QueryClient();
function App() {
return (
<QueryClientProvider client={queryClient}>
<YourApp />
</QueryClientProvider>
);
}
就像给应用套了一个 “React Query 上下文”,所有组件才能使用 useQuery
和 useMutation
。
📥 数据读取:useQuery
这是你使用最多的 Hook,用来获取数据:
const { data, isLoading, isFetching, isError } = useQuery(
['posts'],
getPosts
);
解释一下参数:
queryKey
: 唯一标识请求(数组形式,能感知依赖)queryFn
: 实际发起请求的函数(异步)
它返回的状态包括:
data
: 拿到的数据isLoading
: 初次加载中isFetching
: 任意刷新中isError
: 出错了没
🔄 智能刷新机制
React Query 的厉害之处不只是能请求数据,还能聪明地“刷新数据”:
页面重新挂载
浏览器窗口重新聚焦
网络重新连接
queryKey 变化
以上情况会触发“后台静默刷新”,而不是打断用户体验显示 loading。
💡 用户感知是:页面很快、数据总是新的。
✍️ 数据更新:useMutation
如果你想做的是“写操作” —— 比如新增、编辑、删除 —— 就用 useMutation
:
const mutation = useMutation(savePost, {
onSuccess: (savedPost) => {
// 这里可以更新缓存
},
});
核心 API 是:
mutation.mutate(data);
状态变量:
isLoading
: 正在提交isSuccess
: 提交成功isError
: 出错啦
📦 缓存更新策略:3 种方式
✅ 1. 失效刷新
最推荐的方式,安全简单:
queryClient.invalidateQueries(['posts']);
表示:“这份数据老了,下次触发重新请求”。
⚡️ 2. 乐观更新(Optimistic Update)
用户体验最好的方式,但要小心回滚:
onMutate: () => { /* 先更新缓存 */ }
onError: () => { /* 请求失败时回滚 */ }
🛠 3. 手动更新缓存
适合你知道新数据该长啥样:
queryClient.setQueryData(['posts'], (old) => [newPost, ...old]);
🧾 示例代码:手动缓存更新
const { mutate } = useMutation(savePost, {
onSuccess: (savedPost) => {
queryClient.setQueryData(['posts'], (oldPosts = []) => [
savedPost,
...oldPosts,
]);
},
});
🧠 总结:为什么学 React Query?
🚀 它能帮你:
写更少的代码,拥有更强的功能
自动处理状态,提升用户体验
统一数据交互逻辑,易维护可扩展
节省你 80% 的 useEffect + useState 写法
在任何一个与后端频繁交互的 React 应用中,React Query 都是你的数据层最佳搭档!
📚 推荐实践任务
🎯 自己动手写一个 “博客列表页面”:
使用
useQuery
请求 posts 列表用
useMutation
提交新博客实现保存成功后自动刷新列表(试试 invalidate + setQueryData 两种方式)
🧰 附加推荐工具: 可以安装 React Query DevTools 浏览器插件,实时观察缓存、请求状态,非常适合调试!