javascript - 设置状态对象以重新获取时反应查询隐藏错误消息
问题描述
在当前的 React 查询中,我正在调用 api,当出现错误时,它会显示错误,但是,当我更改状态对象以进行新调用时,它确实显示加载数据但不隐藏错误消息?我创建了一个示例,我添加了一个按钮,该按钮会给出错误消息,即
stackblitz 示例:https ://stackblitz.com/edit/react-ts-6wugxj?file=index.tsx
import React from 'react';
import { render } from 'react-dom';
import { useQuery } from 'react-query';
import axios from 'axios';
import { QueryClient, QueryClientProvider } from 'react-query';
const App: React.FunctionComponent = () => {
const queryKey = 'getData';
const [number, setNumber] = React.useState(1)
const getData = async (): Promise<any> => {
await new Promise((resolve) => setTimeout(resolve, 1000));
const response = await axios
.get(`https://jsonplaceholder.typicode.com/posts/${number}`)
.then((res) => res.data);
return response;
};
const {
data: result,
isFetching,
status,
error,
refetch,
}: any = useQuery(queryKey, getData, {
refetchOnWindowFocus: false,
staleTime: 0,
cacheTime: 0,
refetchInterval: 0,
});
React.useEffect(() => {
refetch();
}, [number, refetch]);
return (
<div className="Container">
<button onClick={refetch}>Refetch query</button>
<button onClick={() => setNumber(() => 1)}>Get 1</button>
<button onClick={() => setNumber(() => 2)}>Get 2</button>
<button onClick={() => setNumber(() => 3)}>Get 3</button>
<button onClick={() => setNumber(() => 99999)}>Get 99999</button>
{status === 'error' && <div className="mt-5">{error.message}</div>}
{isFetching ? (
<div className="mt-5">Loading data ...</div>
) : (
<div>
{status === 'success' && (
<div>
{/* {result?.map((inner: any, index: number) => {
return <li key={index}>{inner.title}</li>;
})} */}
<p><strong>id:</strong> {result?.id}</p>
<p>{result?.title}</p>
</div>
)}
</div>
)}
</div>
);
};
const queryClient = new QueryClient();
render(
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>,
document.getElementById('root')
);
解决方案
我在这里看到了多种误解:
a
refetch
不会“清除”状态。事实上,react-query 永远不会仅仅因为你重新获取它就从活动查询中删除状态。这就是构建该库的整个 stale-while-revalidate 原则:在获取新数据时显示旧数据,然后在新数据进入时更新屏幕。这正是您的示例中发生的情况。根本原因实际上是完全不同的:您使用相同的缓存键,然后强制调用
refetch
效果。这意味着
a)第一次获取将发生两次(一次来自 useQuery 调用,然后来自重新获取) b)你只会缓存最新的结果,这意味着你并没有真正使用从 react-query 到它的缓存。
最好的方法是将查询执行提取所需的所有依赖项放入查询键中。这也在此处的文档中。
这样,react-query 将:
- 当依赖关系发生变化时自动触发重新获取。
- 如果在后台重新获取时有任何数据,请立即从缓存中为您提供数据。
将数据获取函数 ( ) 移出组件也是最佳实践,getData
这样它就不会意外关闭不属于查询键的内容。
它看起来像这样:
const App: React.FunctionComponent = () => {
const [number, setNumber] = React.useState(1)
const { data, status } = useQuery(['getData', number], () => getData(number));
就这样。没有效果,没有重取。
此外,您提供的一些选项是默认选项:staleTime
默认为zero
,refetchInterval
默认情况下也是关闭的,因此您不必提供它。cacheTime
ofzero
仅当您想在使用查询后立即对其进行垃圾收集时才需要,这通常不是您想要的,尤其是因为键现在实际上正在更改,因为它们中有一个变量。
最后,您可能不想检查isFetching
以卸载整个结果列表。isFetching
每当进行提取时将始终为真,并且它不是状态机的一部分。使用更改键,您可能希望仅在 时显示微调器status === 'loading'
,因为当您第一次在数字之间切换时,您将获得这种硬加载状态。
推荐阅读
- c# - 在 LINQ 选择中,如何选择列表的 FirstOrDefault?
- java - 我什么时候应该在子类中覆盖超类的方法?如果没有额外的功能,是否必须覆盖所有超类的方法?
- 2d - 在 gekko 的 bspline 函数中格式化 x 和 y 数据时遇到问题
- r - MS Access:类型转换错误(双至长整数)
- php - 从 laravel 5.1 修改
- excel - 如何从工作表数据填充用户定义的类型数组
- php - 是否可以从 mysql 获取记录,例如 January to March(2019) 、 April to June(2018) 下表等
- c# - C#中DataGridView的错误列中的数据检索
- matlab - 稳定性验证器命令“isstable”中的混淆
- bots - linkedin API 是否支持聊天机器人?