React-Query useInfiniteQuery排序切换后分页数据顺序未更新问题
React-Query useInfiniteQuery 切换排序后分页顺序未更新的解决方案
问题核心原因
- Query Key未包含排序参数:当前自定义Hook的queryKey仅包含
documentDesignRevisions和designName,排序变更时React-Query会判定为同一查询,直接复用旧缓存数据 - 手动refetch未重置分页状态:切换排序后调用refetch只会重新获取当前页,但旧分页数据仍保留在缓存中,导致新旧数据混杂,顺序不符合预期
修复步骤
1. 更新Query Key,纳入排序参数
修改自定义Hook的queryKey,将sort加入其中,让React-Query识别不同排序为独立查询:
export function useGetDocumentDesignRevisionsQuery( designName: string, options: Options, ) { const { limit, sort } = options const fetchRevisions = ({ pageParam = 0 }) => { return DesignManagerApi.getDocumentDesignRevisions(designName, { offset: pageParam, limit, sort, }) } const normalizeResultData = (data: ReturnedData) => { return { pages: [...data.pages], pageParams: [...data.pageParams], } } // 加入sort到queryKey数组,区分不同排序的查询 return useInfiniteQuery(['documentDesignRevisions', designName, sort], fetchRevisions, { select: normalizeResultData, }) }
2. 移除手动refetch的useEffect
由于Query Key已包含排序参数,当sortedBy变化时,自定义Hook会自动触发新查询,无需手动调用refetch,删除以下代码:
// 移除该useEffect useEffect(() => { getDocumentDesignRevisionsQuery.refetch() }, [sortedBy])
3. 修复加载更多的分页参数逻辑
加载更多时,需基于当前排序下的最后一页数据计算下一页偏移量,避免使用固定值:
function loadMoreRevisions() { const queryData = getDocumentDesignRevisionsQuery.data if (!queryData || queryData.pages.length === 0) return // 根据接口返回的实际分页结构计算下一页offset const lastPage = queryData.pages[queryData.pages.length - 1] const nextOffset = lastPage.offset + REVISIONS_LIST_LIMIT getDocumentDesignRevisionsQuery.fetchNextPage({ pageParam: nextOffset, }) }
4. 可选:主动重置查询状态(按需使用)
若需要在切换排序时立即清空旧分页数据,可在排序切换函数中调用reset:
const sortItems = (info: SortedBy) => { setSortedBy({ key: info.key, order: info.order === 'desc' ? 'asc' : 'desc', }) // 重置查询状态,清空现有分页数据 getDocumentDesignRevisionsQuery.reset() }
补充说明
- 不同排序规则会生成独立的Query Key,各自拥有独立缓存,切换排序时自动拉取对应排序的第一页数据,再次切回旧排序时可直接复用缓存
- 若无需保留旧排序缓存,可在切换排序时调用
queryClient.removeQueries(['documentDesignRevisions', designName])清理所有相关缓存
内容的提问来源于stack exchange,提问作者Jamal
相关产品推荐
相关产品推荐

