首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >大厂都在用 @tanstack/react-query 到底有多好用!

大厂都在用 @tanstack/react-query 到底有多好用!

作者头像
萌萌哒草头将军
发布2025-09-15 14:26:24
发布2025-09-15 14:26:24
9100
代码可运行
举报
文章被收录于专栏:前端框架前端框架
运行总次数:0
代码可运行

前言

最近参与新的项目了,发现项目居然使用了 @tanstack/react-query,以前之后简单介绍过,今天再来详细上手使用下!

@tanstack/react-query
@tanstack/react-query

@tanstack/react-query

往期精彩推荐

正文

@tanstack/react-query 是 TanStack 生态的一部分,专为 React、Vue 等框架设计,用于管理服务器状态和异步数据。

它无需全局状态库,就能处理数据获取、缓存、突变和同步,支持 TS/JS,并提供开发工具。

以下是 React Query 的详细使用过程

准备
代码语言:javascript
代码运行次数:0
运行
复制
pnpm add @tanstack/react-query

然后在根入口处使用 Provider!

代码语言:javascript
代码运行次数:0
运行
复制
import React from"react";
import {
  QueryClient,
  QueryClientProvider
} from"@tanstack/react-query";
import Layout from"@/Layout";

exportdefaultfunction App() {
// 创建 QueryClient 实例
const queryClient = new QueryClient();

return (
    <QueryClientProvider client={queryClient}>
      <Layout />
    </QueryClientProvider>
  );
}

useQuery 请求数据

useQuery 用于数据获取,支持自动缓存、重取和错误处理!

代码语言:javascript
代码运行次数:0
运行
复制
import React from"react";
import { useQuery } from"@tanstack/react-query";
import axios from"axios";

function fetchUser(userId: number) {
return axios.get(`https://jsonplaceholder.typicode.com/users/${userId}`).then(res => res.data);
}

function User({ userId }: { userId: number }) {
const { data, isLoading, isError, error, refetch } = useQuery({
    queryKey: ["user", userId], // 缓存 key
    queryFn: () => fetchUser(userId),
    // 数据在缓存中保持 1 分钟为新鲜,不会重复请求
    staleTime: 1000 * 60,
    // 数据缓存 5 分钟
    cacheTime: 1000 * 60 * 5,
    // 请求失败自动重试 2 次
    retry: 2,
    onError: (err) => {
      console.error("获取用户数据失败:", err);
    }
  });

if (isLoading) return<div>加载中...</div>;
if (isError) return<div>出错了: {(error as Error).message}</div>;

return (
    <div>
      <h2>{data.name}</h2>
      <p>Email: {data.email}</p>
      <button onClick={() => refetch()}>手动触发重取</button>
    </div>
  );
}

staleTime 的默认值为 0 ,也就是说立马失效,不会缓存!

2. 突变与更新(useMutation)

useMutation 用于数据更新,如 POST 请求,支持乐观更新和回滚。

代码语言:javascript
代码运行次数:0
运行
复制
import React, { useState } from"react";
import {
  useQuery,
  useMutation,
  useQueryClient
} from"@tanstack/react-query";
import axios from"axios";


// 模拟获取待办列表
const fetchTodos = () => axios.get("/api/todos").then(res => res.data);

// 模拟添加待办
const addTodo = (text: string) => axios.post("/api/todos", { text }).then(res => res.data);

exportfunction Todos() {
const queryClient = useQueryClient();
const [newText, setNewText] = useState("");

// 获取待办列表
const { data: todos = [] } = useQuery({ queryKey: ["todos"], queryFn: fetchTodos });

// useMutation 用于新增待办
const mutation = useMutation({
    mutationFn: addTodo,

    // 乐观更新
    onMutate: async (text: string) => {
      await queryClient.cancelQueries({ queryKey: ["todos"] });

      const previousTodos = queryClient.getQueryData<any[]>(["todos"]);

      // 立即更新缓存,显示新增项
      queryClient.setQueryData(["todos"], [...(previousTodos || []), { id: Date.now(), text }]);

      return { previousTodos }; // 返回上下文,用于失败回滚
    },

    // 出错时回滚
    onError: (_err, _variables, context: any) => {
      if (context?.previousTodos) {
        queryClient.setQueryData(["todos"], context.previousTodos);
      }
    },

    // 成功后刷新缓存
    onSettled: () => {
      queryClient.invalidateQueries({ queryKey: ["todos"] });
    }
  });

return (
    <div>
      <h2>待办列表</h2>
      <ul>
        {todos.map(todo => (
          <li key={todo.id}>{todo.text}</li>
        ))}
      </ul>

      <input value={newText} onChange={e => setNewText(e.target.value)} placeholder="新增待办" />
      <button onClick={() => mutation.mutate(newText)}>添加</button>
    </div>
  );
}
并行/依赖查询

并行查询时只需要写多个 useQuery 即可,

代码语言:javascript
代码运行次数:0
运行
复制
const userQuery = useQuery({
  queryKey: ["user", userId],
  queryFn: () => fetchUser(userId),
});

const postsQuery = useQuery({
  queryKey: ["posts", userId],
  queryFn: () => fetchPosts(userId),
});

如果需要依赖查询,则需要使用 enabled 属性!

代码语言:javascript
代码运行次数:0
运行
复制
const userQuery = useQuery({
queryKey: ["userByName", username],
queryFn: () => axios.get(`/api/users?username=${username}`).then(res => res.data),
});

const postsQuery = useQuery({
queryKey: ["posts", userQuery.data?.id],
queryFn: () => axios.get(`/api/users/${userQuery.data.id}/posts`).then(res => res.data),
// 只有当 userQuery 获取到 id 时才触发
enabled: !!userQuery.data?.id,
});
开发工具集成

开发时,可以搭配它的开发者工具,

代码语言:javascript
代码运行次数:0
运行
复制
import React from"react";
import { QueryClient, QueryClientProvider, useQuery } from"@tanstack/react-query";
import { ReactQueryDevtools } from"@tanstack/react-query-devtools";
import Layout from"@/Layout";

// 创建 QueryClient
const queryClient = new QueryClient();

exportdefaultfunction App() {
return (
    <QueryClientProvider client={queryClient}>
      <Layout />
      <ReactQueryDevtools initialIsOpen={false} position="bottom-right" />
    </QueryClientProvider>
  );
}
开发者工具
开发者工具

开发者工具

点击打开控制面板,是这样的:

最后

@tanstack/react-query 解决了数据管理的痛点,通过 useQueryuseMutation 等钩子,让代码更简洁、更可靠。感兴趣的话感觉用它来优化你的项目吧!

今天的分享就这些了,感谢大家的阅读!如果文章中存在错误的地方欢迎指正!

往期精彩推荐
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-08-22,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 萌萌哒草头将军 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
    • 往期精彩推荐
  • 正文
    • 准备
    • useQuery 请求数据
    • 2. 突变与更新(useMutation)
    • 并行/依赖查询
    • 开发工具集成
  • 最后
    • 往期精彩推荐
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档