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

🎙 欢迎来到《前端达人 · 播客书单》第 28 期。

视频版博客观看更精彩

今天我们正式进入数据交互领域的高效解法 ------ React Query

如果你还在用 useEffect + useState 写 API 请求逻辑、维护加载状态、写 try/catch 和 loading 错误处理的锅山代码...... 那这期内容你一定不能错过。

❓ 为什么我们需要 React Query?

传统的 React 中,发起请求的方式通常是这样的:

go 复制代码
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 带来的是这样的体验:

go 复制代码
const { data, isLoading, isError } = useQuery(['posts'], fetchPosts);

就这?对,就这!异步请求、缓存策略、错误处理、后台刷新......统统一行搞定!

🧠 React Query 是什么?

一句话定义:

一个用于 异步数据获取、缓存、同步和更新服务器状态 的 React 库。

它解决的是"远程数据状态管理"的问题,而不是本地 UI 状态。

✅ 它的优势包括:

  • 自动缓存数据,并且感知依赖变化自动刷新

  • 简化异步请求逻辑,减少样板代码

  • 自动处理 loading / error 状态

  • 支持窗口聚焦、网络重连刷新

  • 拥有 Devtools,调试体验超爽

🧩 核心入口:QueryClientProvider

想使用 React Query,第一步是全局配置 QueryClient

go 复制代码
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';

const queryClient = new QueryClient();

function App() {
  return (
    <QueryClientProvider client={queryClient}>
      <YourApp />
    </QueryClientProvider>
  );
}

就像给应用套了一个 "React Query 上下文",所有组件才能使用 useQueryuseMutation

📥 数据读取:useQuery

这是你使用最多的 Hook,用来获取数据:

go 复制代码
const { data, isLoading, isFetching, isError } = useQuery(
  ['posts'],
  getPosts
);

解释一下参数:

  • queryKey: 唯一标识请求(数组形式,能感知依赖)

  • queryFn: 实际发起请求的函数(异步)

它返回的状态包括:

  • data: 拿到的数据

  • isLoading: 初次加载中

  • isFetching: 任意刷新中

  • isError: 出错了没

🔄 智能刷新机制

React Query 的厉害之处不只是能请求数据,还能聪明地"刷新数据":

  • 页面重新挂载

  • 浏览器窗口重新聚焦

  • 网络重新连接

  • queryKey 变化

以上情况会触发"后台静默刷新",而不是打断用户体验显示 loading。

💡 用户感知是:页面很快、数据总是新的。

✍️ 数据更新:useMutation

如果你想做的是"写操作" ------ 比如新增、编辑、删除 ------ 就用 useMutation

go 复制代码
const mutation = useMutation(savePost, {
  onSuccess: (savedPost) => {
    // 这里可以更新缓存
  },
});

核心 API 是:

go 复制代码
mutation.mutate(data);

状态变量:

  • isLoading: 正在提交

  • isSuccess: 提交成功

  • isError: 出错啦

📦 缓存更新策略:3 种方式

✅ 1. 失效刷新

最推荐的方式,安全简单:

go 复制代码
queryClient.invalidateQueries(['posts']);

表示:"这份数据老了,下次触发重新请求"。

⚡️ 2. 乐观更新(Optimistic Update)

用户体验最好的方式,但要小心回滚:

go 复制代码
onMutate: () => { /* 先更新缓存 */ }
onError: () => { /* 请求失败时回滚 */ }

🛠 3. 手动更新缓存

适合你知道新数据该长啥样:

go 复制代码
queryClient.setQueryData(['posts'], (old) => [newPost, ...old]);

🧾 示例代码:手动缓存更新

go 复制代码
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 浏览器插件,实时观察缓存、请求状态,非常适合调试!

相关推荐
晚霞的不甘3 分钟前
Flutter for OpenHarmony《智慧字典》 App 主页深度优化解析:从视觉动效到交互体验的全面升级
前端·flutter·microsoft·前端框架·交互
我是伪码农5 分钟前
Vue 1.28
前端·javascript·vue.js
鹓于9 分钟前
Excel一键生成炫彩二维码
开发语言·前端·javascript
siwangdexie_new10 分钟前
html格式字符串转word文档,前端插件( html-docx-js )遇到兼容问题的解决过程
前端·javascript·html
子春一24 分钟前
Flutter for OpenHarmony:构建一个智能长度单位转换器,深入解析 Flutter 中的多字段联动、输入同步与工程化表单设计
开发语言·javascript·flutter
2601_9496130226 分钟前
flutter_for_openharmony家庭药箱管理app实战+用药提醒列表实现
服务器·前端·flutter
利刃大大27 分钟前
【Vue】scoped作用 && 父子组件通信 && props && emit
前端·javascript·vue.js
-凌凌漆-35 分钟前
【Vue】Vue3 vite build 之后空白
前端·javascript·vue.js
心柠35 分钟前
前端工程化
前端
摘星编程42 分钟前
用React Native开发OpenHarmony应用:useImperativeHandle暴露实例方法
javascript·react native·react.js