@tanstack/react-query v4中Suspense返回数据过快问题修复方案
React Query v4升级后Suspense场景下数据处理时机问题修复
问题根源
React Query v4 调整了onSuccess的执行时机:它现在作为渲染后副作用执行,组件会先拿到原始查询数据再触发onSuccess处理逻辑;而v3中onSuccess是在数据写入缓存后、组件重新渲染前执行的。这就导致你的组件在onSuccess完成数据处理前,就尝试访问未初始化的content属性,从而抛出Cannot read properties of undefined (reading 'content')错误。
修复方案
方案1:在queryFn内部处理数据(推荐)
将数据处理逻辑直接整合到查询函数中,确保返回给组件的是已处理完成的数据:
export function usePageView( uuid: string, ): UseQueryResult<DrupalPage[], Error> { return useQuery<DrupalPage[], Error>( queryKeyUsePageView(uuid), async () => { // 先获取原始数据 const rawData = await fetchAnon(getPageByPageUuid(uuid)); // 直接在查询阶段处理数据 if (rawData?.length) { return rawData.map(element => processResult(element)); } return rawData; }, { cacheTime: YEAR_MILLISECONDS, staleTime: YEAR_MILLISECONDS, // 移除原有的onSuccess配置 }, ); }
方案2:使用select选项转换数据
如果希望查询逻辑和数据处理逻辑分离,可以用select选项在数据进入缓存前完成转换:
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, select: (rawData) => { // 在此处处理数据,组件将直接获取处理后的结果 if (rawData?.length) { return rawData.map(element => processResult(element)); } return rawData; }, }, ); }
说明
以上两种方案都是在数据被传递给组件之前完成处理,确保组件拿到的是直接可用的、已处理的数据,完全对齐v3中依赖onSuccess处理数据后的组件行为。
另外注意:你的组件代码中id={uuid}疑似笔误,应为id={pageUuid},如果是复制失误请自行修正。
内容的提问来源于stack exchange,提问作者Patrick Kenny
相关产品推荐
相关产品推荐

