首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >React-query:如何使用useInfiniteQuery分页

React-query:如何使用useInfiniteQuery分页
EN

Stack Overflow用户
提问于 2020-06-01 18:02:35
回答 3查看 6.3K关注 0票数 8

我想使用react-query的useInfiniteQuery。除了分页之外,一切看起来都很清楚。

文档示例如下:

代码语言:javascript
复制
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,
    }
  )

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

EN

回答 3

Stack Overflow用户

发布于 2020-08-15 17:37:10

我正在尝试用rick和morty API制作无限滚动,下面是我是如何实现的:

您的函数(getCharacters)应该接受一个key和一个属性(nextPage),并返回一个对象,该对象包含从您的fetch中获取的数据(data)和页面标识符(nextPage)加1。

代码语言:javascript
复制
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和Morty API的更好示例

代码语言:javascript
复制
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
  }
})
票数 3
EN

Stack Overflow用户

发布于 2021-09-30 10:21:31

具体步骤如下:

通过在getNextPageParam.

  • Calling

  • 函数中为下一个查询提供信息,
  1. 等待useInfiniteQuery请求第一组数据。

参考https://react-query.tanstack.com/guides/infinite-queries

使用rest api的示例1

代码语言:javascript
复制
  const fetchProjects = ({ pageParam = 0 }) =>
     fetch('/api/projects?cursor=' + pageParam)
 
   const {
     data,
     isLoading,
     fetchNextPage,
     hasNextPage,
   } = useInfiniteQuery('projects', fetchProjects, {
     getNextPageParam: (lastPage) => {
       // lastPage signature depends on your api respond, below is a pseudocode
       if (lastPage.hasNextPage) {
         return lastPage.nextCursor;
       }
         return undefined;
     },
   })

使用graphql查询的示例2(伪代码)

代码语言:javascript
复制
  const {
    data,
    fetchNextPage,
    isLoading,
  } = useInfiniteQuery(
    ['GetProjectsKeyQuery'],
    async ({ pageParam }) => {
      return graphqlClient.request(GetProjectsQuery, {
        isPublic: true, // some condition/variables if you have
        first: NBR_OF_ELEMENTS_TO_FETCH, // 10 to start with
        cursor: pageParam,
      });
    },
    {
      getNextPageParam: (lastPage) => {
         // pseudocode, lastPage depends on your api respond
        if (lastPage.projects.pageInfo.hasNextPage) {
          return lastPage.projects.pageInfo.endCursor;
        }
        return undefined;
      },
    },
  );

react-query将创建包含名为pages的数组的data。每次使用新的光标/页面/偏移量调用api时,它都会将新页面添加到页面中。您可以对数据执行flatMap操作,例如:

const projects = data.pages.flatMap((p) => p.projects.nodes)

当你想在下一批中再次调用fetchNextPage时,在代码中的某个地方调用api,例如:

代码语言:javascript
复制
  const handleEndReached = () => {
    fetchNextPage();
  };

Graphql示例查询:

添加到您的查询after: cursor

代码语言:javascript
复制
  query GetProjectsQuery($isPublic: Boolean, $first: Int, $cursor: Cursor) {
  projects(
    condition: {isPublic: $isPublic}
    first: $first
    after: $cursor
  ) ...
票数 3
EN

Stack Overflow用户

发布于 2020-08-29 04:06:32

函数getFetchMore()有一个lastGroup参数。使用这个参数,您必须检查您的响应(lastGroup参数)是否有更多的数据需要获取。在本例中,我返回了一个page变量,它将是您调用fetchMore()时要获取的下一个页面,我们的fetchPlanets()异步函数将这个page变量作为参数获取,以便对新的api_url执行concat()操作。

我在获取窗口焦点时遇到了一个问题,因为它在获取下一个组(page)时出现了问题。因此,我在options参数中传递了refetchOnWindowFocus: false

代码语言:javascript
复制
const fetchPlanets = async (key, page = '1') => {
  const api_url = `https://swapi.dev/api/planets/?page=${page}`;
  console.log(api_url);
  const res = await fetch(api_url);
  return res.json();
};

const Planets = () => {
  const { status, data, isFetching, isFetchingMore, fetchMore, canFetchMore } = useInfiniteQuery(
    ['planets'],
    fetchPlanets,
    {
      refetchOnWindowFocus: false,
      onSuccess: () => console.log('data fetch with no problemo!'),
      onError: () => console.log('data fetch error!'),
      getFetchMore: (lastGroup) => {
        lastGroup.page = lastGroup.next?.split('=')[1];
        return lastGroup.page;
      },
    },
  );

  console.log('data', data);
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/62129771

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档