React Query 是一个用于处理和缓存异步数据的库,它可以帮助我们更轻松地管理应用程序中的数据流,并提供一些适用于复杂数据场景下的高级功能。本文将介绍 React Query 的基本使用方法。
安装
你可以使用 pnpm 或 yarn 来安装 React Query:
pnpm install react-query
# 或者
yarn add react-query
基本用法
以下是使用 React Query 的示例:
import { useQuery } from 'react-query';
function App() {
const { isLoading, error, data } = useQuery('repoData', () =>
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
res.json()
)
);
if (isLoading) {
return <div>Loading...</div>;
}
if (error) {
return <div>{error.message}</div>;
}
return (
<div>
<h1>{data.name}</h1>
<p>{data.description}</p>
</div>
);
}
在上面的代码中,首先使用 useQuery hook 来获取远程数据并缓存它。传递了一个字符串 'repoData' 作为查询键,以及一个返回 Promise 的函数。useQuery hook 将执行这个函数,并缓存其结果。如果再次调用 useQuery hook 并传递相同的查询键,则会直接返回缓存的数据而不是再次从远程服务器请求数据。
配置
在使用 React Query 时,可以通过传递配置选项来自定义其行为。以下是一些常用的配置选项:
- staleTime:缓存时间(以毫秒为单位),在这段时间内不会重新获取数据。
- cacheTime:缓存时间(以毫秒为单位),在这段时间后缓存将被清除。
- retry:是否允许重试失败的请求。
- retryDelay:重试之间的延迟时间(以毫秒为单位)。
- refetchOnWindowFocus:当窗口聚焦时是否重新获取数据。
- enabled:是否启用查询,可以根据条件动态禁用查询。
你可以在官方文档中查看更多的配置选项:https://react-query.tanstack.com/reference/useQuery#options
预加载和无限滚动
React Query 还提供了一些高级功能,如预加载和无限滚动。以下是这些功能示例:
预加载
预加载是指在用户需要数据之前就开始获取和缓存数据,以提高应用程序的响应速度。
function App() {
const { isLoading, error, data } = useQuery('repoData', () =>
fetch('https://api.github.com/repos/tannerlinsley/react-query').then(res =>
res.json()
),
{
// 开启预加载
refetchOnMount: 'always',
// 设置预加载延迟时间(以毫秒为单位)
refetchIntervalInBackground: 10000,
}
);
// ...
}
在上面的代码中,我们首先通过传递 refetchOnMount 属性来开启预加载,并将其值设置为 'always'。然后,使用 refetchIntervalInBackground 属性来设置预加载的延迟时间(以毫秒为单位)。
无限滚动
无限滚动是指在用户滚动页面时,自动加载更多的数据。
function App() {
const [page, setPage] = useState(1);
const { isLoading, error, data, isFetching } = useInfiniteQuery(
'repoData',
({ pageParam = 1 }) =>
fetch(`https://api.github.com/repos/tannerlinsley/react-query/issues?page=${pageParam}&per_page=10`).then(res =>
res.json()
),
{
getNextPageParam: (lastPage, allPages) => {
const nextPage = lastPage.length === 10 ? allPages.length + 1 : false;
return nextPage;
},
}
);
const handleLoadMore = () => {
setPage(prevPage => prevPage + 1);
};
// ...
}
在上面的代码中,首先使用 useInfiniteQuery hook 来获取和缓存无限数量的远程数据。与 useQuery 相比,useInfiniteQuery 允许按需加载更多的数据。
还使用了 getNextPageParam 属性来指定如何获取下一页的页码。在这个例子中,检查最后一页是否为满页(即有 10 条数据),如果是,则返回下一页的页码,否则返回 false 并终止加载更多的数据。
最后,使用 isFetching 属性来指示是否正在请求数据,并在页面底部呈现一个“加载更多”的按钮。
React Query 提供了一些高级功能,例如预加载和无限滚动,可以帮助我们更好地管理应用程序中的数据流。使用 refetchOnMount 和 refetchIntervalInBackground 属性可以开启预加载,而使用 useInfiniteQuery hook 可以实现无限滚动。如果需要自定义 React Query 的行为,则可以传递配置选项来实现。
自定义查询钩子
除了 useQuery 和 useInfiniteQuery 之外,React Query 还允许创建自定义的查询钩子来处理其他类型的数据流。
以下是一个简单的自定义查询钩子示例:
import { useQuery } from 'react-query';
function useUserData(userId) {
return useQuery(['userData', userId], () =>
fetch(`https://api.github.com/users/${userId}`).then(res => res.json())
);
}
function App() {
const { isLoading, error, data } = useUserData('tannerlinsley');
// ...
}
在上面的代码中,使用 useUserData hook 来获取和缓存用户信息。传递一个字符串数组 ['userData', userId] 作为查询键,并通过 fetch 函数从远程服务器获取数据。在 App 组件中,使用这个自定义 hook 来获取用户数据。
处理 mutations
除了查询操作之外,React Query 还提供了用于处理 mutations(如添加、删除或修改)的 useMutation hook。
以下是一个简单的添加用户的 mutation 示例:
import React, { useState } from 'react';
import { useMutation, useQueryClient } from 'react-query';
function AddUser() {
const queryClient = useQueryClient();
const [username, setUsername] = useState('');
const [password, setPassword] = useState('');
const { mutate, isLoading } = useMutation(
values =>
fetch('/api/users', {
method: 'POST',
body: JSON.stringify(values),
headers: {
'Content-Type': 'application/json',
},
}),
{
onSuccess: () => {
queryClient.invalidateQueries('users');
setUsername('');
setPassword('');
},
}
);
const handleSubmit = event => {
event.preventDefault();
mutate({ username, password });
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={username}
onChange={event => setUsername(event.target.value)}
placeholder="Username"
/>
<input
type="password"
value={password}
onChange={event => setPassword(event.target.value)}
placeholder="Password"
/>
<button type="submit" disabled={isLoading}>
{isLoading ? 'Adding User...' : 'Add User'}
</button>
</form>
);
}
在上面的代码中,首先使用 useQueryClient hook 来获取查询客户端的实例。然后,使用 useMutation hook 来构建一个添加用户的 mutation。
当用户提交表单时,调用 mutate 函数来触发 mutation。如果 mutation 成功,则通过 onSuccess 属性通知查询客户端更新缓存,并清除表单数据。
React Query 提供了处理 mutations 的 useMutation hook,并允许创建自定义的查询钩子来处理其他类型的数据流。在处理 mutations 时,我们可以使用 onSuccess 属性来通知查询客户端更新缓存。
有任何问题,请直接留言,我将一一回复