React  infinite scroll in few lines
Tags: react, webdev, javascript
Published: 2020-08-09 22:35:22

## Introduction

### What is infinite scroll ?  
Infinite scrolling is a web-design technique that loads content continuously as the user scrolls down the page, eliminating the need for pagination.
Some sites where you can see usage of infinity scroll are for example: [Twitter](https://twitter.com/home), [9gag](https://9gag.com/) etc...

## What are we going to build

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/yeephr06xje655t1iorc.gif)

I know nothing to fancy looking, but you can improve and style it, so it looks better, this is just a basic example and introducting a concept

## Prerequisites 

* This tutorial assumes that you have working knowledge of React
* We are going to Use [React Hooks](https://reactjs.org/docs/hooks-intro.html)
* Before we get started, ensure that you have Node, Yarn, or npm installed in your environment.
* Have a Web browser offcourse

## Getting started

```
npx create-react-app infiniteScroll
```

Once you have finished creating the project folder you can cd into it, and run it:

```
cd infiniteScroll 
npm start
```

This will run the app in development mode and you can view it in the browser using the link http://localhost:3000/.

**It will look like this:**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/je1u2a5w1hvvnfqtpr7v.png)

## Component Setup

Create new Infinite scroll component and paste following code inside it:

```
import React, { useState  } from 'react';
// styling post container
const divStyle = {
    color: 'blue',
    height: '250px',
    textAlign: 'center',
    padding: '5px 10px',
    background: '#eee',
    marginTop: '15px'
};

// styling container wrapper
const containerStyle = {
    maxWidth: '1280px',
    margin: '0 auto',
}

const InfiniteScroll = () => {
    // initialize list of posts
    const [postList, setPostList] = useState({
        list: [1,2,3,4]
    }); 


    return (<div className="container" style={containerStyle}>
        <div className="post-list">
            {
                postList.list.map((post, index) => {
                    return (<div key={index} 
                             className="post" 
                             style={divStyle}>
                        <h2> {post } </h2>
                    </div>)
                })
            }
            <div className="loading">
                    <h2>Load More</h2>
           </div>
        </div>
    </div>)
}

export default InfiniteScroll;
```

**Your page will now look like this:**

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/m1a2vfc3sjxhvvuakvvg.png)

## Adding infinite scroll

For this we would use [**Interaction Observer API**](https://developer.mozilla.org/en-US/docs/Web/API/Intersection_Observer_API)
Intersection Observer is a really awesome JavaScript API that simplifies scroll-based events in JavaScript. Rather than constantly checking the distance from the top, Intersection Observer watches when an element enters or exits the viewport.

We will use interaction Observer to watch when user enters specific point and then load more posts.

 - *First we will import **useRef** and **useEffect** hook from React and attach them to Load More div*
 - *then will register IntersectionObserver on Load More div when component is mounted*
 - *add new state variable page, that will track on what page we currently are. To simulate more real life example how we would do it when connecting with backend* 
 - *the last step when page is update, simply just load more posts*

#### Here is a complete code:
```
import React, { useEffect, useState, useRef  } from 'react';

const divStyle = {
    color: 'blue',
    height: '250px',
    textAlign: 'center',
    padding: '5px 10px',
    background: '#eee',
    marginTop: '15px'
};


const containerStyle = {
    maxWidth: '1280px',
    margin: '0 auto',
}
const InfiniteScroll = () => {
    const [postList, setPostList] = useState({
        list: [1,2,3,4]
    }); 
    // tracking on which page we currently are
    const [page, setPage] = useState(1);
    // add loader refrence 
    const loader = useRef(null);
    
    useEffect(() => {
         var options = {
            root: null,
            rootMargin: "20px",
            threshold: 1.0
         };
        // initialize IntersectionObserver
        // and attaching to Load More div
         const observer = new IntersectionObserver(handleObserver, options);
         if (loader.current) {
            observer.observe(loader.current)
         }

    }, []);


    useEffect(() => {
        // here we simulate adding new posts to List
        const newList = postList.list.concat([1,1,1,1]);
        setPostList({
            list: newList
        })
    }, [page])

    // here we handle what happens when user scrolls to Load More div
   // in this case we just update page variable
    const handleObserver = (entities) => {
        const target = entities[0];
        if (target.isIntersecting) {   
            setPage((page) => page + 1)
        }
    }


    return (<div className="container" style={containerStyle}>
        <div className="post-list">
            {
                postList.list.map((post, index) => {
                    return (<div key={index} className="post" style={divStyle}>
                        <h2> {post } </h2>
                    </div>)
                })
            }
             <!-- Add Ref to Load More div -->
            <div className="loading" ref={loader}>
                    <h2>Load More</h2>
           </div>
        </div>
    </div>)
}

export default InfiniteScroll;
```

This is my first post on Dev.to Thank you for reading :)

If you liked this post, you can find more by:

Following me on Twitter: