使用 React 手动刷新 react-query onClick
Posted
技术标签:
【中文标题】使用 React 手动刷新 react-query onClick【英文标题】:Manually refresh react-query onClick with React 【发布时间】:2021-12-17 20:29:13 【问题描述】:当我重新获取我的查询时,当我有一个 onClick 按钮时它会进入“正在更新...”状态,但我希望查询重新获取并显示“正在加载...”状态。我的代码是:
https://stackblitz.com/edit/react-ts-jfq8ve?file=index.tsx
import React, useEffect 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 [value, setValue] = React.useState<number>(7);
const queryKey = 'getData';
const getData = async (): Promise<any> =>
await new Promise((resolve) => setTimeout(resolve, 1000));
const response = await axios
.get(`https://jsonplaceholder.typicode.com/todos`)
.then((res) => res.data);
return response;
;
const
data: result,
status,
isRefetching,
error,
refetch,
: any = useQuery(queryKey, getData,
refetchOnWindowFocus: true,
staleTime: 0,
cacheTime: 0,
refetchInterval: 0,
);
useEffect(() =>
refetch();
, [value, refetch]);
return (
<div className="Container">
<button onClick=() => setValue(prevValue => prevValue + 1 )>Set value</button>
isRefetching ? <p className="mt-3">Updating data...</p> : null
status === 'error' && <div className="mt-5">error.message</div>
status === 'loading' && <div className="mt-5">Loading data ...</div>
status === 'success' && (
<div>
result?.map((inner: any, index: number) =>
return <li key=index>inner.title</li>;
)
</div>
)
</div>
);
;
const queryClient = new QueryClient();
render(
<QueryClientProvider client=queryClient>
<App />
</QueryClientProvider>,
document.getElementById('root')
);
【问题讨论】:
【参考方案1】:根据Yozi的回答,我删除了useEffect
,只是将refetch
函数放到了按钮的onClick
。
const
data: result,
isFetching,
status,
error,
refetch,
: any = useQuery(queryKey, getData,
refetchOnWindowFocus: true,
staleTime: 0,
cacheTime: 0,
refetchInterval: 0,
);
return (
<div className="Container">
<button onClick=refetch>Refetch query</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>;
)
</div>
)
</div>
)
</div>
);
;
在线示例:https://stackblitz.com/edit/react-ts-j87pub?file=index.tsx
【讨论】:
【参考方案2】:status === loading
如果查询处于“硬”加载状态。这意味着没有缓存数据,
query
当前正在获取...
我猜你不需要为你的特殊情况使用status === loading
。使用isFetching
- 它涵盖了初始加载和重新获取
import React, useEffect 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 [value, setValue] = React.useState<number>(7);
const queryKey = 'getData';
const getData = async (): Promise<any> =>
await new Promise((resolve) => setTimeout(resolve, 1000));
const response = await axios
.get(`https://jsonplaceholder.typicode.com/todos`)
.then((res) => res.data);
return response;
;
const
data: result,
status,
isFetching,
error,
refetch,
: any = useQuery(queryKey, getData,
refetchOnWindowFocus: true,
staleTime: 0,
cacheTime: 0,
refetchInterval: 0,
);
useEffect(() =>
refetch();
, [value, refetch]);
return (
<div className="Container">
<button onClick=() => setValue(prevValue => prevValue + 1 )>Set value</button>
status === 'error' && <div className="mt-5">error.message</div>
isFetching && <div className="mt-5">Loading data ...</div>
status === 'success' && (
<div>
result?.map((inner: any, index: number) =>
return <li key=index>inner.title</li>;
)
</div>
)
</div>
);
;
const queryClient = new QueryClient();
render(
<QueryClientProvider client=queryClient>
<App />
</QueryClientProvider>,
document.getElementById('root')
);
【讨论】:
如何根据上面的代码实现改变?以上是关于使用 React 手动刷新 react-query onClick的主要内容,如果未能解决你的问题,请参考以下文章
使用 React/Typescript 的 React-query 数据的 SetState
使用 MSW 测试 React-query,并将数据传递给子组件
react-query:useQuery 返回 undefined 并且组件不会重新渲染