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 请求场景。通过 useQuery
、useMutation
、useInfiniteQuery
等 API,我们可以轻松实现数据的缓存、自动同步和优化用户体验。
6.详细用法请参照官方文档
https://tanstack.com/query/latest/docs/framework/react/overview