使用React来实现无限滚动。(Handson、react-query、react-infinite-scroller)

首先

这是上一次使用的库版本。这是使用 react-query 和 react-infinite-scroller 结合的实现。

 

产出

 

~/develop/HITOTSU/react_infinity_scroll$ tree -I node_modules 
.
├── README.md
├── package.json
├── public
│   ├── favicon.ico
│   ├── index.html
│   ├── logo192.png
│   ├── logo512.png
│   ├── manifest.json
│   └── robots.txt
├── src
│   ├── App.tsx
│   ├── components
│   │   ├── ReactQueryInfiteScrollSample.tsx
│   │   └── UseInfiniteScrollSample.tsx
│   ├── hooks
│   │   └── useInfiniteScroll.tsx
│   ├── index.tsx
│   ├── logo.svg
│   └── type.ts
├── tsconfig.json
└── yarn.lock

5 directories, 17 files
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import {QueryClient, QueryClientProvider} from 'react-query';

const root = ReactDOM.createRoot(
  document.getElementById('root') as HTMLElement
);
const queryClient = new QueryClient();

root.render(
  <React.StrictMode>
    <QueryClientProvider client={queryClient}>
      <App />
    </QueryClientProvider>
  </React.StrictMode>
);
import React from 'react';
import { UseInfiniteScrollSample } from './components/UseInfiniteScrollSample'

function App() {
  return (
    <UseInfiniteScrollSample />
  );
}

export default App;
import {FC, useRef} from 'react';
import InfiniteScroll from 'react-infinite-scroller';
import React from 'react';
import axios from 'axios';
import {useInfiniteQuery} from 'react-query';

export const ReactQueryInfiteScrollSample: FC = () => {
  const containerRef = useRef(null);
  const LIMIT = 10;

  const fetchData = async (page: number) => {
    console.log('fetchData call page', page);
    const response = await axios.get<Post[]>(`https://jsonplaceholder.typicode.com/posts?_page=${page}`);
    const data = response.data;
    return data;
  };

  const {data, isLoading, isFetching, hasNextPage, fetchNextPage} = useInfiniteQuery(
    'todos',
    ({pageParam = 1}) => fetchData(pageParam),
    {
      getNextPageParam: (lastPage, allPages) => {
        const nextPage = lastPage.length === LIMIT ? allPages.length + 1 : undefined;
        return nextPage;
      },
    }
  );

  if (isLoading) return <div />;

  return (
    <div>
      <div style={{height: '2000px'}}>無限スクロール</div>
      {isFetching && <div className="loading">Loading...</div>}
      <div ref={containerRef}>
        <InfiniteScroll loadMore={(page) => fetchNextPage({pageParam: page})} hasMore={hasNextPage}>
          {data?.pages.map((page, i) => (
            <div key={i}>
              {page.map((item: Post) => (
                <div key={item.id}>
                  <p>
                    {item.id}{item.title}
                  </p>
                </div>
              ))}
            </div>
          ))}
        </InfiniteScroll>
      </div>
    </div>
  );
};

interface Post {
  userId: number;
  id: number;
  title: string;
  body: string;
}

bannerAds