React Query 简单用法总结

491 阅读2分钟

1. React Query 简介

React Query 是一个用于管理服务器状态的库,提供了高效的数据获取、缓存、同步和更新机制。

为什么使用 React Query?

  • 自动缓存和后台同步,减少不必要的 API 调用
  • 提供请求状态管理(loading、error、success 等)
  • 支持分页、无限滚动和实时数据同步
  • 使数据获取更具声明性,减少手动管理状态的复杂性

2. 核心 API 及用法

2.1 useQuery —— 获取数据

useQuery 用于执行 GET 请求,自动处理缓存和后台刷新。

示例:获取用户数据

import { useQuery } from '@tanstack/react-query';
import axios from 'axios';

const fetchUser = async () => {
  const { data } = await axios.get('/api/user');
  return data;
};

export default function UserProfile() {
  const { data, isLoading, error } = useQuery({ queryKey: ['user'], queryFn: fetchUser });

  if (isLoading) return <p>Loading...</p>;
  if (error) return <p>Error: {error.message}</p>;

  return <div>Welcome, {data.name}!</div>;
}

2.2 useMutation —— 变更数据(POST/PUT/DELETE)

useMutation 用于 创建、更新或删除 数据。

示例:提交表单

import { useMutation } from '@tanstack/react-query';
import axios from 'axios';

const createUser = async (user) => {
  const { data } = await axios.post('/api/user', user);
  return data;
};

export default function CreateUser() {
  const mutation = useMutation({ mutationFn: createUser });

  const handleSubmit = async () => {
    mutation.mutate({ name: 'John Doe', age: 30 });
  };

  return (
    <div>
      <button onClick={handleSubmit} disabled={mutation.isLoading}>
        {mutation.isLoading ? 'Creating...' : 'Create User'}
      </button>
      {mutation.isError && <p>Error: {mutation.error.message}</p>}
      {mutation.isSuccess && <p>User created!</p>}
    </div>
  );
}

2.3 useInfiniteQuery —— 无限加载

用于 分页滚动加载 数据。

示例:滚动加载文章

import { useInfiniteQuery } from '@tanstack/react-query';
import axios from 'axios';

const fetchPosts = async ({ pageParam = 1 }) => {
  const { data } = await axios.get(`/api/posts?page=${pageParam}`);
  return data;
};

export default function Posts() {
  const {
    data,
    fetchNextPage,
    hasNextPage,
    isFetchingNextPage
  } = useInfiniteQuery({
    queryKey: ['posts'],
    queryFn: fetchPosts,
    getNextPageParam: (lastPage, pages) => lastPage.nextPage
  });

  return (
    <div>
      {data?.pages.map((page, i) => (
        <div key={i}>{page.posts.map((post) => <p key={post.id}>{post.title}</p>)}</div>
      ))}
      <button onClick={() => fetchNextPage()} disabled={!hasNextPage || isFetchingNextPage}>
        {isFetchingNextPage ? 'Loading...' : hasNextPage ? 'Load More' : 'No More Posts'}
      </button>
    </div>
  );
}

2.4 useQueryClient —— 手动更新缓存

可用于 数据同步乐观更新

示例:删除用户并更新缓存

import { useMutation, useQueryClient } from '@tanstack/react-query';
import axios from 'axios';

const deleteUser = async (id) => {
  await axios.delete(`/api/user/${id}`);
};

export default function UsersList() {
  const queryClient = useQueryClient();
  const mutation = useMutation({
    mutationFn: deleteUser,
    onSuccess: () => {
      queryClient.invalidateQueries(['users']); // 让缓存失效,触发重新获取数据
    }
  });

  return (
    <button onClick={() => mutation.mutate(1)}>Delete User</button>
  );
}

3. 适用场景

适合使用 React Query 的场景

  • 需要自动缓存和后台同步的 API 请求(避免重复请求)
  • 需要分页、滚动加载useInfiniteQuery
  • 需要数据变更和手动更新缓存useMutation + useQueryClient
  • 需要自动轮询或实时数据同步refetchInterval
  • 需要进行乐观更新以提升用户体验

不适合使用 React Query 的场景

  • 本地组件状态管理(例如 useState 适用于组件内部数据)
  • 需要手动深度管理状态(Redux 可能更合适)

4. 其他高级用法

4.1 enabled 选项(控制请求时机)

useQuery({
  queryKey: ['user', id],
  queryFn: fetchUser,
  enabled: !!id // 当 id 存在时才请求
});

4.2 轮询数据(实时更新)

useQuery({ queryKey: ['stock'], queryFn: fetchStock, refetchInterval: 5000 });

4.3 预获取数据(SSR/SSG)

export async function getServerSideProps() {
  const queryClient = new QueryClient();
  await queryClient.prefetchQuery(['user'], fetchUser);
  return {
    props: { dehydratedState: dehydrate(queryClient) },
  };
}

5. 结论

React Query 让数据获取和状态管理更加简单高效,适用于各种 API 请求场景。通过 useQueryuseMutationuseInfiniteQuery 等 API,我们可以轻松实现数据的缓存、自动同步和优化用户体验。

6.详细用法请参照官方文档

tanstack.com/query/lates…