从 useEffect 解放出来!异步请求 + 缓存刷新 + 数据更新,React Query全搞定

发布于:2025-09-02 ⋅ 阅读:(15) ⋅ 点赞:(0)

🎙 欢迎来到《前端达人 · 播客书单》第 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 浏览器插件,实时观察缓存、请求状态,非常适合调试!


网站公告

今日签到

点亮在社区的每一天
去签到