具有多个参数的InfiniteScroll

问题描述 投票:0回答:1
import InfiniteScroll from 'react-infinite-scroll-component';
import { useSearchParams } from 'react-router-dom';
import { useInfiniteQuery } from '@tanstack/react-query';

export const fetchData = async ({
  page = 1,
  limit = 10,
  sort = 'firstName',
}) => {
  console.log('function page:', page);
  const response = await fetch(
    `http://localhost:5000/data/datas?page=${page}&limit=${limit}&sort=${sort}`
  );
  return response.json();
  // response:
  //{
  //    "data": [],
  //    "hasNextPage": false, // totalItems - page * limit > 0;
  //    "totalItems": 100
  //  }
};

function MyComponent() {
  const [searchParam, setSearchParam] = useSearchParams();
  const page = parseInt(searchParam.get('page')) || 1;
  const limit = parseInt(searchParam.get('limit')) || 25;
  const sort = searchParam.get('sort') || 'firstName';
    
  const {
    isLoading,
    error,
    data,
    fetchNextPage,
    hasNextPage
  } = useInfiniteQuery({
    queryKey: ['data', sort],
    queryFn: () => {
      return fetchData({ page, limit, sort });
    },
    initialPageParam: 1,
    getNextPageParam: (lastPage, allPages) => {
      // console.log('lastPage?.hasNextPage', lastPage?.hasNextPage);
      return lastPage.hasNextPage ? allPages.length + 1 : undefined;
    },
  });

  if (isLoading) {
    return <div>Loading...</div>;
  }

  if (error) {
    return <div>Error: {error.message}</div>;
  }
  console.log('data', data);

  const datas = data?.pages.reduce((acc, page) => {
    return [...acc, ...page.data];
  }, []);

  const fetchMore = () => {
    // const page = Number(searchParam.get('page')) || 1;
    searchParam.set('page', page + 1);
    setSearchParam(searchParam);

    fetchNextPage();
  };

  return (
    <div>
      <h1>Infinite scroll</h1>
      <InfiniteScroll
        dataLength={datas ? datas.length : 0}
        next={fetchMore}
        hasMore={hasNextPage}
        loader={<div>loading more...</div>}
        endMessage={<div>you have reach the end, MF!</div>}
      >
        {datas && datas.map((data) => (
          <h1 key={data?._id}>
            {data?.firstName} - {data?.lastName}
          </h1>
        ))}
      </InfiniteScroll>
    </div>
  );
}

export default MyComponent;

我想使用infinitescroll和useInifiniteQuery,并传递多个参数,如排序和限制。我正在获取数据并默认获取第一个数据数组(参数中没有页面)。但问题是,当我调用 fetchmore 时,我得到了相同的数据(第一次),但当我尝试获取新数据时,它就起作用了。 因此我最终进入了一个不应该存在的页面。例如,如果我的最大页数是 10,由于第一个数组的重复,我会达到 11。

示例:

pages={
    0:[1, 2, 3], // same data
    1:[1, 2, 3], // same data
    2:[4, 5, 6],
    3:[7, 8, 9]
}

如何避免两次调用第一个数据块的冗余?

reactjs react-query react-infinite-scroll-component
1个回答
0
投票

根据您的代码,您的问题可能来自 URL 参数和 React Query 之间的交互。要解决该问题,请从 URL 中删除 page 参数,因为 React Query 在内部处理分页,并使用启用选项来控制查询运行的时间。我将给出一个例子,如下代码

 const [searchParam, setSearchParam] = useSearchParams();
  const limit = parseInt(searchParam.get('limit')) || 25;
  const sort = searchParam.get('sort') || 'firstName';
    
  const {
    isLoading,
    error,
    data,
    fetchNextPage,
    hasNextPage
  } = useInfiniteQuery({
    queryKey: ['data', sort],
    queryFn: ({ pageParam = 1 }) => {
      return fetchData({ 
        page: pageParam, 
        limit, 
        sort 
      });
    },
    initialPageParam: 1,
    getNextPageParam: (lastPage, allPages) => {
      return lastPage.hasNextPage ? allPages.length + 1 : undefined;
    },
  });

  // Rest of the component remains same, but modify fetchMore:
  const fetchMore = () => {
    fetchNextPage();
  };

https://tanstack.com/query/v5/docs/framework/react/guides/infinite-queries

© www.soinside.com 2019 - 2024. All rights reserved.