使用 react-query 查询失败时面临无限渲染。
useQuery
仅应在 queryKey
更改时重新获取,或者根据 retry
参数请求失败时重新获取。
为什么
queryFn
被重新执行?
可重现的示例:https://stackblitz.com/edit/ilias-react-query-loop?file=src%2Fmain.tsx
const queryClient = new QueryClient({
defaultOptions: { queries: { retry: false } },
});
const useFailingQuery = () =>
useQuery({
queryKey: ['static'],
queryFn() {
console.log('Fetching...');
throw new Error('Fail');
return {};
},
});
const Component = () => {
useFailingQuery();
return <h1>Component</h1>;
};
const App = () => {
const { isLoading } = useFailingQuery();
// This causes infinite query retry
if (isLoading) {
return <span>Loading...</span>;
}
return <Component />;
};
ReactDOM.createRoot(document.getElementById('root')!).render(
<React.StrictMode>
<QueryClientProvider client={queryClient}>
<App />
</QueryClientProvider>
</React.StrictMode>
);
最后,我只需要在
<Component />
加载完成时渲染useFailingQuery()
,并在加载时渲染页面范围的骨架。
虽然我无法弄清楚
useQuery()
循环,但解决方法是始终渲染组件:
const App = () => {
const { isLoading } = useFailingQuery();
return <>
{isLoading && <span>Loading...</span>}
<Component />
</>;
};