代码之家  ›  专栏  ›  技术社区  ›  Patrick Kenny

Suspendse在@tanstack/rect查询v4中返回数据过快

  •  0
  • Patrick Kenny  · 技术社区  · 2 年前

    我正在将一个React应用程序从React query v3升级到@tanstack/rect 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:无法读取未定义的属性(读取“content”)

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

    问题似乎是在v4中 WrapperPageEdit 在之前刷新 on成功 usePageView 查询已完成处理,而在v3中,组件 包装页编辑 直到 on成功 data.map 已完成。

    如何正确修复此问题?我可以写一些额外的代码来尝试检查 on成功 data.map 是完整的,但由于react查询在v3中自动处理了这一点,我想在v4中重写我的代码,使其保持不变。

    0 回复  |  直到 2 年前
        1
  •  1
  •   TkDodo    2 年前

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

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

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

    推荐文章