You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.20 10:33:28