React Query isSuccess触发报错及无限渲染等技术问题求助
问题原因与修复方案
1. 无限重渲染的根源
你直接在组件渲染流程里执行setFetchedInvoiceData和toast.error,触发了循环:
- 当
fetchInvoices.isSuccess为true时,调用setFetchedInvoiceData更新状态,强制组件重新渲染 - 组件重新渲染时又会再次检测
isSuccess状态,重复执行状态更新操作,最终触发React的重渲染限制
2. Toast警告的原因
toast.error本质是更新Toast容器组件的状态,但你在App组件的渲染阶段调用它,React不允许在渲染一个组件的同时更新另一个组件的状态,因此抛出警告。
修复方案
推荐方案:用React Query内置回调处理副作用
直接在useQuery配置中定义onSuccess和onError回调,这是React Query官方推荐的处理请求后逻辑的方式:
const searchInvoiceList = async ( plantLoc: string, invoiceOption: string ) => { try { // 替换await+then的混合写法,用try/catch更简洁 const response = await axios.get(`${linkURL}inv/getControlList/${plantLoc}/${invoiceOption}`); return response.data.sqlData; } catch (error) { console.error(error); throw error; // 必须抛出错误,让React Query捕获到isError状态 } }; const fetchInvoices = useQuery({ queryKey: [ "invoiceData", plantLocationOptionChecked.value, invoiceOptionChecked.value, ], queryFn: () => searchInvoiceList( plantLocationOptionChecked.value, invoiceOptionChecked.value ), enabled: false, retry: 0, // 请求成功后的回调 onSuccess: (data) => { if (data.length === 0) { toast.error("Search Results were empty"); } setFetchedInvoiceData(data); }, // 请求失败后的回调 onError: (error) => { console.log(error); }, }); // 移除原来的if(isSuccess)、if(isError)渲染阶段逻辑
备选方案:用useEffect监听状态变化
如果需要更灵活的逻辑控制,可以通过useEffect监听fetchInvoices的状态变化,避免在渲染阶段执行副作用:
const fetchInvoices = useQuery({ queryKey: [ "invoiceData", plantLocationOptionChecked.value, invoiceOptionChecked.value, ], queryFn: () => searchInvoiceList( plantLocationOptionChecked.value, invoiceOptionChecked.value ), enabled: false, retry: 0, }); useEffect(() => { if (fetchInvoices.isSuccess) { if (fetchInvoices.data.length === 0) { toast.error("Search Results were empty"); } setFetchedInvoiceData(fetchInvoices.data); } if (fetchInvoices.isError) { console.log(fetchInvoices.error); } }, [fetchInvoices.isSuccess, fetchInvoices.isError, fetchInvoices.data]);
额外优化提示
- 原
searchInvoiceList中await和.then/.catch混合的写法冗余,改成try/catch更符合异步代码规范 - 必须在
catch中抛出错误,否则React Query无法正确识别请求失败状态
内容的提问来源于stack exchange,提问作者Zach philipp
相关产品推荐
相关产品推荐

