前端使用 React Query 管理“服务器状态”的方法
作者: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 服务器状态内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
