How to implement infinite scroll in next js?
Asked Answered
S

1

9

Infinite scrolling in next js is not working, the same code works on normal create-react-app

Sonia answered 20/5, 2021 at 16:40 Comment(0)
S
29

Unlike in normal React Js, infinite scrolling in NextJs has a different approach. Here we will be using an npm package called react-infinite-scroll-component.

Let's see the index.js file index.js

import Content from "./Content";

export default function index(props) {
  return (
    <>
      <div>
        <Content data={props.data} />
      </div>
    </>
  );
}

export const getStaticProps = async () => {
  const data = await fetch(
    "https://jsonplaceholder.typicode.com/todos?_limit=10"
  ).then((response) => response.json());
  return {
    props: { data }
  };
};

In the above code, you can see that we are fetching data from getStaticProps, which returns the json data as props, and we are receiving that prop and passing it to the component. If you observe carefully, we are limiting the initial rendering to 10, so, first 10 data will be shown and then we'll again fetch data from the server.

Now, let's see the content page Content.js

import React, { useState } from "react";
import InfiniteScroll from "react-infinite-scroll-component";

const Content = ({ data }) => {
  const [posts, setPosts] = useState(data);
  const [hasMore, setHasMore] = useState(true);

  const getMorePost = async () => {
    const res = await fetch(
      `https://jsonplaceholder.typicode.com/todos?_start=${posts.length}&_limit=10`
    );
    const newPosts = await res.json();
    setPosts((post) => [...post, ...newPosts]);
  };

  return (
    <>
      <InfiniteScroll
        dataLength={posts.length}
        next={getMorePost}
        hasMore={hasMore}
        loader={<h3> Loading...</h3>}
        endMessage={<h4>Nothing more to show</h4>}
      >
        {posts.map((data) => (
          <div key={data.id}>
            <div className="back">
              <strong> {data.id}</strong> {data.title}
            </div>
            {data.completed}
          </div>
        ))}
      </InfiniteScroll>
      <style jsx>
        {`
          .back {
            padding: 10px;
            background-color: dodgerblue;
            color: white;
            margin: 10px;
          }
        `}
      </style>
    </>
  );
};

export default Content;

Here we are getting more posts from the server after all the data loads. The code is self-explanatory.

setPosts((post) => [...post, ...newPosts]);

With the above state, we are appending the previous data to the incoming data

You can check this code sandbox for the visual of how it is actually working.

https://codesandbox.io/s/next-js-infinite-scroll-3vfem

Sonia answered 20/5, 2021 at 16:40 Comment(4)
so we gave up on pre-rendering the page, right ? or how can we implement a page like pre-render 10 posts, the rest will come from getMorePost() ?Plotinus
now we are doing client side for infinite scroll? won't that reveal API urls in client side?Naseby
@JatinHemnan You can create an api route for it and call it from your api, no?Harridan
@Harridan you mean like /api/something yeah that will workNaseby

© 2022 - 2024 — McMap. All rights reserved.