React Query + react-infinite-scroller实现带自定义请求头的无限滚动问题
问题描述
使用react-query结合react-infinite-scroller实现无限滚动列表,基础功能已正常工作,但初始请求无法携带自定义请求头中的token:
- 后续分页请求通过
getNextPageParam返回的token能正常传递给fetchNextItems,请求有效 - 尝试配置
initialData未解决问题 - 希望保留API调用的抽离结构,不将其移至JSX函数组件内,寻求可行解决方案
相关代码
List.tsx
[...] const idToken = useAppSelector(getIdToken) const { data, isLoading, isError, hasNextPage, fetchNextPage } = useInfiniteQuery(queryKey, fetchNextItems, { getNextPageParam: lastPage => { if (lastPage.nextPage < lastPage.totalPages) return { idToken, page: lastPage.nextPage } return undefined }, //initialData: {} }) [...] <InfiniteScroll hasMore={hasNextPage} loadMore={fetchNextPage} getScrollParent={() => document.getElementById('main')} useWindow={false} > {data.pages.map(page => page?.data.map(item => ( <Component key={item._id} itemData={item} /> )), )} </InfiniteScroll>
api.ts
export const fetchNextItems = async ({ pageParam = { idToken: '', page: 0 }, }) => { const response = await fetch( `${URL}?$skip=${pageParam.page * limit}&$limit=${limit}`, { headers: new Headers({ Authentication: pageParam.idToken, }), }, ) const { data, total } = await response.json() return { data, nextPage: pageParam.page + 1, totalPages: Math.ceil(total / limit), } }
解决方案
方法1:配置initialPageParam传递初始token
这是最直接的解决方式,在useInfiniteQuery的配置项中添加initialPageParam,将当前获取到的idToken和初始页码传入,确保初始请求能拿到有效token:
const { data, isLoading, isError, hasNextPage, fetchNextPage } = useInfiniteQuery(queryKey, fetchNextItems, { initialPageParam: { idToken, page: 0 }, // 新增配置 getNextPageParam: lastPage => { if (lastPage.nextPage < lastPage.totalPages) return { idToken, page: lastPage.nextPage } return undefined }, })
方法2:将token加入queryKey,适配token更新场景
如果idToken可能在组件生命周期内刷新或变化,可以把idToken加入queryKey数组。这样当token更新时,react-query会自动重新触发初始请求,保证请求携带最新的token:
// 修改queryKey,将token作为查询标识的一部分 const queryKey = ['list', idToken] const { data, isLoading, isError, hasNextPage, fetchNextPage } = useInfiniteQuery(queryKey, fetchNextItems, { initialPageParam: { idToken, page: 0 }, getNextPageParam: lastPage => { if (lastPage.nextPage < lastPage.totalPages) return { idToken, page: lastPage.nextPage } return undefined }, })
补充说明
fetchNextItems中pageParam的默认值可以保留,但initialPageParam传入的参数会覆盖默认值,确保初始请求的token有效- 以上方案均无需修改API调用的抽离结构,保持现有代码组织方式即可
内容的提问来源于stack exchange,提问作者Canuma
相关产品推荐
相关产品推荐

