首页 > 解决方案 > React-query:如何使用 useInfiniteQuery 进行分页

问题描述

我想使用 react-query 的useInfiniteQuery. 一切似乎都很清楚,但分页,部分。

文档示例是:

export default () => {
  const {
    status,
    data,
    error,
    isFetching,
    isFetchingMore,
    fetchMore,
    canFetchMore,
  } = useInfiniteQuery(
    'projects',
    async (key, nextId = 0) => {
      const { data } = await axios.get('/api/projects?cursor=' + nextId)
      return data
    },
    {
      getFetchMore: lastGroup => lastGroup.nextId,
    }
  )

我明白它的作用。projects是查询的 id,用于缓存,然后是执行 api 调用的函数。现在nextId变量呢?它从零开始,所以后端会知道它必须只返回从 0 到 x 的结果(顺便说一下,我们也可以通过动态限制吗?)。但是,当fetchMore()调用再次触发查询的函数时,究竟如何useInfiniteQuery知道它应该递增nextId

标签: reactjs

解决方案


我正在尝试使用 rick and morty API 进行无限滚动,这是我实现它的方式:

您的函数 ( getCharacters) 应该接受 akey和 prop ( nextPage) 并返回一个对象,该对象包括data来自您的 fetch 的数据 ( ) 和页面标识符 ( nextPage) 加 1。

const getCharacters = async (key, nextPage = 1) => {
  const res = await fetch(`${BASE_URL}/character/?page=${nextPage}`);
  const { results } = await res.json();
  return {
    data: results,
    nextPage: nextPage + 1,
  };
};

const { status, data, fetchMore } = useInfiniteQuery(
  'characters',
  getCharacters,
  {
    getFetchMore: (lastGroup, allGroups) => lastGroup.nextPage, // nextPage because we named it nextPage
  }
);

const paginatedData = [];
data.forEach((page) => {
  page.data.forEach((char) => {
    paginatedData.push(char);
  });
});

console.log(paginatedData) // The whole data

更新:

使用 Rick and Morty API 的更好示例

async function getCharacters(page: number): Promise<Response> {
    const response = await fetch('https://rickandmortyapi.com/api/character?page=' + page)
    const characters = (await response.json())
    return characters;
}

const { ... } = useInfiniteQuery(['characters'], ({ pageParam = 1 }) => getCharacters(pageParam), {
  getNextPageParam: (lastPage) => {
    const nextUrl = lastPage.info.next
    if (nextUrl) {
      // Return next page number
      return Number(nextUrl.charAt(nextUrl.length - 1))
    }
    // Return false means no next page
    return false
  }
})

推荐阅读