【问题标题】:Suspense returns data too fast in @tanstack/react-query v4Suspense 在@tanstack/react-query v4 中返回数据太快
【发布时间】:2022-07-21 20:44:11
【问题描述】:

我正在将 React 应用程序从 react-query v3 升级到 @tanstack/react-query v4。

几乎一切正常,但我遇到了 Suspense 问题。

我有一个反应组件:

const WrapperPageEdit: React.FC<MyProps> = ({
  pageUuid,
  redirect,
}: MyProps) => {
  const FormPage = React.lazy(() => import('./FormPage'));
  const { data } = usePageView(pageUuid);

  if (data?.[0]) {
    const pageObjectToEdit= data[0];
    const content = pageObjectToEdit.myStuff.content;

    return (
      <Suspense
        fallback={<Trans id="loading.editor">Loading the editor...</Trans>}
      >
        <FormPage
          id={uuid}
          content={content}
          redirect={redirect}
        />
      </Suspense>
    );
  }
  return <p>No data.</p>;
};

这是我的查询:

export function usePageView(
  uuid: string,
): UseQueryResult<DrupalPage[], Error> {
  return useQuery<DrupalPage[], Error>(
    queryKeyUsePageView(uuid),
    async () => {
      return fetchAnon(getPageByPageUuid(uuid));
    },
    {
      cacheTime: YEAR_MILLISECONDS,
      staleTime: YEAR_MILLISECONDS,
      onSuccess: (data) => {
        if (data?.[0]) {
          data.map((element) => processResult(element));
        }
      },
    },
  );
}

这在 v3 中有效,但在 v4 中失败并出现以下错误:

TypeError: Cannot read properties of undefined (reading 'content')

属性未定义的原因是因为该属性是由onSuccess (data.map) 中的处理设置的。

问题似乎是在 v4 中,组件 WrapperPageEditusePageView 查询完成处理之前刷新,而在 v3 中,组件 WrapperPageEdit 直到 onSuccess 才刷新data.map 已完成。

如何正确解决此问题?我可以编写一些额外的代码来尝试检查 onSuccess data.map 是否完整,但是由于 react-query 在 v3 中自动处理了这个,我想在 v4 中重写我的代码,以便它是相同的。

【问题讨论】:

  • 不确定我是否理解代码 - data.map(processResult) 在做什么?它会改变结果吗?这也是您在 v3 中不应该做的事情。为什么不直接在 queryFn 中做呢?
  • 是的,它正在改变结果(根据返回的数据,计算一些新属性并将它们添加到data)。我从来没有在 queryFn 中这样做过,因为......我没想过那样做。这更有意义。随时发布答案,我会接受。

标签: react-query


【解决方案1】:

问题很可能是您正在更改onSuccess 中的数据。在回调中直接修改数据不是一个好主意。相反,例如直接在 queryFn 中进行转换:

async () => {
  const data = fetchAnon(getPageByPageUuid(uuid));
  if (data?.[0]) {
    data.map((element) => processResult(element));
  }
  return data
},

其他进行数据转换的好地方是例如select 选项,但它应该始终以不可变的方式发生,否则,您会无意中覆盖缓存的数据。 React 更喜欢更新是不可变的。

【讨论】:

    猜你喜欢
    • 2023-01-24
    • 2022-10-18
    • 1970-01-01
    • 2022-08-19
    • 2018-03-22
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 2018-11-28
    相关资源
    最近更新 更多