You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.13 16:03:10