React Query修改状态触发重新请求时未隐藏已有错误消息如何解决
问题根因
- 你当前的
useQuery查询键是固定字符串getData,没有将请求依赖的number变量纳入查询键。React Query 依赖查询键区分不同的请求,当number变化时,React Query 会判定为同个查询的重新拉取,因此会保留之前的错误状态,直到新请求执行完成才会更新状态,这就导致加载过程中旧错误一直展示。 - 错误信息的渲染逻辑没有加加载状态的判断,只要
status为error就显示,和加载提示的判断逻辑是并行的,因此两个内容会同时出现。
解决方案
方案1:调整查询键(推荐)
将number作为依赖项放入查询键数组,同时可以删除手动触发请求的useEffect,React Query 会在查询键变化时自动发起新请求,且新请求会重置之前的错误、数据状态,完全符合预期。
方案2:修改渲染逻辑
如果业务需要复用同一个查询键,不想清除旧缓存,可以调整错误信息的渲染条件,加载状态下不展示错误。
修改后完整代码
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 [number, setNumber] = React.useState(1) // 将number放入查询键,作为请求的依赖标识 const queryKey = ['getData', number]; 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, }); 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> {/* 如果使用方案2不改查询键,将此处条件改为 status === 'error' && !isFetching 即可 */} {status === 'error' && <div className="mt-5">{error.message}</div>} {isFetching ? ( <div className="mt-5">Loading data ...</div> ) : ( <div> {status === 'success' && ( <div> <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') );
内容的提问来源于stack exchange,提问作者Sole
相关产品推荐
相关产品推荐

