前端使用 React Query 管理“服务器状态”的方法

 更新时间:2025年11月17日 10:20:12   作者:weixin79893765432...  
文章介绍了如何安装和使用React Query来管理服务器状态,文章提供了一个实战项目示例,展示了如何使用React Query来实现获取、新增、删除和自动刷新Todo列表等功能,感兴趣的朋友跟随小编一起看看吧

一、安装注册 react-query

首先要安装 @tanstack/react-query:

npm install @tanstack/react-query

然后在入口文件中必须加 QueryClientProvider:

// main.tsx / index.tsx
import { QueryClient, QueryClientProvider } from '@tanstack/react-query';
import App from './App';
const queryClient = new QueryClient();
export default function Root() {
  return (
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  );
}

二、使用 react-query

使用的 React Query 管理“服务器状态”的步骤:

  • 获取数据(useQuery)
  • 创建数据(useMutation)
  • 更新与删除
  • 缓存、重新请求、乐观更新
  • 实战项目文件结构

【举个例子】:
假设有一个服务器 API /api/todos。现在需要你实现以下需求:
①、获取 Todo 列表
②、新增 Todo
③、删除 Todo
④、自动刷新、缓存、错误处理

1、定义获取数据的查询函数 fetchTodos

// api/todoApi.ts
export const fetchTodos = async () => {
  const res = await fetch('/api/todos');
  if (!res.ok) throw new Error('Failed to fetch todos');
  return res.json();
};
export const addTodo = async (title: string) => {
  const res = await fetch('/api/todos', {
    method: 'POST',
    body: JSON.stringify({ title }),
    headers: { 'Content-Type': 'application/json' }
  });
  if (!res.ok) throw new Error('Failed to add todo');
  return res.json();
};
export const deleteTodo = async (id: number) => {
  const res = await fetch(`/api/todos/${id}`, {
    method: 'DELETE'
  });
  if (!res.ok) throw new Error('Failed to delete todo');
  return res.json();
};

2、使用 useQuery 获取服务器状态

import { useQuery } from '@tanstack/react-query';
import { fetchTodos } from './api/todoApi';
export function TodoList() {
  const { data, isLoading, error } = useQuery({
    queryKey: ['todos'],      // 缓存 key(全局唯一)
    queryFn: fetchTodos,      // 请求函数
    staleTime: 5000,          // 5 秒内不重新请求
    refetchOnWindowFocus: false, // 切回窗口不重新请求
  });
  if (isLoading) return <div>加载中...</div>;
  if (error) return <div>加载失败</div>;
  return (
    <ul>
      {data.map(todo => (
        <li key={todo.id}>{todo.title}</li>
      ))}
    </ul>
  );
}

3、新增数据(useMutation + 自动刷新列表)

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { addTodo } from './api/todoApi';
export function AddTodo() {
  const queryClient = useQueryClient();
  const mutation = useMutation({
    mutationFn: (title: string) => addTodo(title),
    onSuccess() {
      // 手动刷新 todos 列表
      queryClient.invalidateQueries(['todos']);
    },
  });
  const handleAdd = () => {
    mutation.mutate('新的任务');
  };
  return (
    <button onClick={handleAdd} disabled={mutation.isPending}>
      {mutation.isPending ? '添加中...' : '添加 TODO'}
    </button>
  );
}

4、删除数据(useMutation + 乐观更新)

React Query 的强大之处是:可以不用等服务器响应,先更新 UI,失败再回滚:

import { useMutation, useQueryClient } from '@tanstack/react-query';
import { deleteTodo } from './api/todoApi';
export function DeleteTodoButton({ id }) {
  const queryClient = useQueryClient();
  const mutation = useMutation({
    mutationFn: () => deleteTodo(id),
    // 乐观更新
    onMutate: async () => {
      await queryClient.cancelQueries(['todos']);
      const previousTodos = queryClient.getQueryData(['todos']);
      queryClient.setQueryData(['todos'], (old: any[]) =>
        old.filter(todo => todo.id !== id)
      );
      return { previousTodos };
    },
    // 失败时回滚
    onError: (_err, _variables, context) => {
      queryClient.setQueryData(['todos'], context.previousTodos);
    },
    // 成功后真正拉取最新数据
    onSettled: () => {
      queryClient.invalidateQueries(['todos']);
    },
  });
  return (
    <button onClick={() => mutation.mutate()}>
      删除
    </button>
  );
}

5、组件组合

export default function App() {
  return (
    <div>
      <h1>Todo 管理(React Query)</h1>
      <AddTodo />
      <TodoList />
    </div>
  );
}

三、React Query 能做什么?不能做什么?

负责管理“服务器状态”的难点:

  • 缓存
  • 后台刷新
  • 自动请求合并
  • 乐观更新
  • 错误恢复
  • 对象引用稳定性
  • 重新请求策略
  • 全局状态同步

不处理:

  • 本地 UI 状态(modal 是否打开?)
  • 表单状态
  • 跨组件 UI 状态

👉 这些依然由 useState/useReducer/Zustand 来处理。

到此这篇关于前端使用 React Query 管理“服务器状态”的文章就介绍到这了,更多相关React Query 服务器状态内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • react hooks深拷贝后无法保留视图状态解决方法

    react hooks深拷贝后无法保留视图状态解决方法

    这篇文章主要为大家介绍了react hooks深拷贝后无法保留视图状态解决示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • 详解React开发中使用require.ensure()按需加载ES6组件

    详解React开发中使用require.ensure()按需加载ES6组件

    本篇文章主要介绍了详解React开发中使用require.ensure()按需加载ES6组件,非常具有实用价值,需要的朋友可以参考下
    2017-05-05
  • React Ant Design树形表格的复杂增删改操作

    React Ant Design树形表格的复杂增删改操作

    这篇文章主要介绍了React Ant Design树形表格的复杂增删改操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2020-11-11
  • react后台系统最佳实践示例详解

    react后台系统最佳实践示例详解

    这篇文章主要为大家介绍了react后台系统最佳实践示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-01-01
  • 深入理解react-router 路由的实现原理

    深入理解react-router 路由的实现原理

    这篇文章主要介绍了深入理解react-router 路由的实现原理,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • 2个奇怪的react写法

    2个奇怪的react写法

    大家好,我卡颂。虽然React官网用大量篇幅介绍最佳实践,但因JSX语法的灵活性,所以总是会出现奇奇怪怪的React写法。本文介绍2种奇怪(但在某些场景下有意义)的React写法。也欢迎大家在评论区讨论你遇到过的奇怪写法
    2023-03-03
  • react字符串匹配关键字高亮问题

    react字符串匹配关键字高亮问题

    这篇文章主要介绍了react字符串匹配关键字高亮问题,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-12-12
  • Objects are not valid as a React child报错解决

    Objects are not valid as a Rea

    这篇文章主要为大家介绍了Objects are not valid as a React child报错解决方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-12-12
  • React函数式组件的性能优化思路详解

    React函数式组件的性能优化思路详解

    这篇文章主要介绍了React函数式组件的性能优化思路详解,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下
    2021-04-04
  • React Electron生成桌面应用过程

    React Electron生成桌面应用过程

    这篇文章主要介绍了React+Electron快速创建并打包成桌面应用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习吧
    2022-12-12

最新评论