React useInfiniteQuery切换会话时API重复多次调用问题排查
切换会话后InfiniteQuery重复调用历史分页请求的原因及解决办法
问题原因
- 查询Key未区分会话:当前
useInfiniteQuery的查询Key固定为'get_conversation',React Query会基于这个Key缓存分页状态和数据。切换会话时,Key未变化,导致复用了之前会话的分页记录(比如已加载3页,新会话会自动触发3次请求)。 - 分页状态未重置:切换会话时没有清空之前的分页数据,InfiniteQuery会认为需要加载之前已加载过的所有页码来补全数据。
- URL参数错误:API请求URL中存在两个
?,会导致后续参数解析异常,可能间接影响分页逻辑的正确性。
解决方案
1. 为每个会话设置独立的查询Key
将查询Key修改为包含会话唯一标识(如channelId和apiFor)的数组,确保不同会话的缓存和分页状态完全隔离:
export const useGetConversation = (params) => { return useInfiniteQuery( // 加入会话标识作为Key的一部分 ['get_conversation', params.channelId, params.apiFor], ({ pageParam = params.offset }) => getData(params, pageParam), { getNextPageParam: (lastPage, allPages) => { const nextPage = allPages.length + 1 return lastPage.messages.length > 0 ? nextPage : undefined }, enabled: false, onError: onErrorResponse, } ) }
2. 切换会话时重置查询状态
在使用useGetConversation的组件中,监听会话标识(如channelId)的变化,调用reset()清空之前的分页状态,再重新触发第一页请求:
const { data, fetchNextPage, reset } = useGetConversation(currentParams); // 会话切换时重置查询并加载第一页 useEffect(() => { reset(); fetchNextPage(); }, [currentParams.channelId, reset, fetchNextPage]);
3. 修复API请求URL错误
将URL中的第二个?替换为&,确保参数正常解析:
const getData = async (params, pageParam) => { const { channelId, apiFor, page_limit, offset } = params const { data } = await MainApi.get( `/customer/message/details?${apiFor}=${ channelId === 'admin' ? 0 : channelId }&offset=${pageParam}&limit=${page_limit}` ) return data }
内容的提问来源于stack exchange,提问作者user18187956
相关产品推荐
相关产品推荐

