How to create infinite scroll for list of post in mobile and desktop using React

422 Views Asked by At

How can I create an infinite scroll using React/Typescript? I want to display a list of 10 post at first then when the users views the 10th one then another phase of 10 should be loaded on the screen. Kindly help out with a code demo.

This currently what I have achieved which is currently displaying all post

import PostStyles from "../../../components/ui/createPost/_createpost.module.scss"
import CreatePost from "../createPost/createPost"
import Post from "../post/post"
import Modal from "../createPost/Modal"
import { postType } from "../../../util/types"


type mainSectionType = {
  posts:postType[]
}

type postType = {
    _id: string;
    creator: {
      id: string,
      name: string,
      profilePicture: string
    },
    createdAt: string,
    photos: string[],
    post_description: string,
    time_posted: string,
  }

const MainSection = ({posts}:mainSectionType) => {


  return (
    <>
      <Modal />
      <div className={PostStyles.post__create_postContainer}>
        <CreatePost />
      </div>
      <div className={PostStyles.post__posts_container}>
         {
          posts.map((post, index) => {
            return <Post
              key={index}
              post_desc={post.post_description}
              postID={post._id}
              username={post.creator.name}
              timeposted={post.time_posted}
              userImg={post.creator.profilePicture}
              photos={post.photos}
            />
          })
        } 
      </div>

    </>
  )
}

export default MainSection
2

There are 2 best solutions below

0
On BEST ANSWER

You can use this package for infinite scroll ->

package name: 'react-infinite-scroll-component'

example:

State :

   const [startIndex, setStartIndex] = useState(0);
      const [slicedData, setSlicedData] = useState([] as interface type name here);
   const [hasMore, setHasMore] = useState(true);

API response:

   setSlicedData(res.slice(0, 10));

HandleNextData function :

const handleNextData = () => {
        /*endIndex find min index like startIndex start from 0 then + 100 and 
data.length from that minimum number will be endIndex. */
    
const endIndex = Math.min(startIndex + 100, data.length);
        
        /* In nextBatch where startIndex and endIndex represent the index of items 
                in that data. method returns a shallow copy of a portion of an 
                            array into a new array object */


        const nextBatch = data.slice(startIndex, endIndex);
        setSlicedData((prevData) => [...prevData, ...nextBatch] as interface name here);

        setHasMore(endIndex < data.length);

        setStartIndex(endIndex);
};

Component:

<InfiniteScroll
    dataLength={your store data state name here.length}                     
    next={handleNextData}
    hasMore={hasMore}
    loader={<h4>Loading more 2 items...</h4>}
    scrollableTarget='scrollableDiv'
>
    {Children}
</InfiniteScroll>
1
On
const handleScroll = () => {
const windowHeight = window.innerHeight;
const documentHeight = document.documentElement.offsetHeight;
const scrollTop = window.pageYOffset || document.documentElement.scrollTop;
const isBottom = scrollTop + windowHeight >= documentHeight;

 if (isBottom && !isLoading) {
   fetchMorePosts();
 }
};

useEffect(() => {
window.addEventListener('scroll', handleScroll);

return () => {
  window.removeEventListener('scroll', handleScroll);
 };
}, [handleScroll]);

You can use this code for it. I hope it helps.