Now, create a state variable to store data from API:

state = {

data: [],

per: 3,

page: 1,

total_pages: null,

};

Use a function to fetch data from an API

loadUser = () => {

const { per, page, data } = this.state;

const url = `https://reqres.in/api/users? per_page=${per}&page=${page}`;

fetch(url)

.then(response => response.json())

.then(json =>

this.setState({

data: son.data,

scrolling: false,

total_pages: json.total_pages

})

);

};

And render it:

render() {

return (

<ul>

{this.state.data.map(data => (

<li key={data.id}>

<div>

<div>

<img src={data.avatar} />

</div>

<div>{data.first_name}</div>

<div>{data.last_name}</div>

</div>

</li>

))}

</ul>

);

}

Rendering the component when the page loads- this can be achieved using componentWillMount .

componentWillMount() {

this.loadUser();

}

And the result:

Loading More Data

So, before loading the next page on-scroll, we need to load more data.

Add a new state variable called prevState to get next page value and call loadUser .

loadMore = () => {

this.setState(

prevState => ({

page: prevState.page + 1,

scrolling: true

}),

this.loadUser

);

};

Call this function on clicking Load More button.

<div>

<ul>

{this.state.data.map(data => (

<li key={data.id}>

<div>

<div>

<img src={data.avatar} />

</div>

<div>{data.first_name}</div>

<div>{data.last_name}</div>

</div>

</li>

))}

</ul>

<button

onClick={e => {

this.loadMore();

}}

>

Load More

</button>

</div>

The result…

So, this is pretty awesome but we have a problem: the old data gets replaced by the new one.

To solve this, append the new response to the old data.

fetch(url)

.then(response => response.json())

.then(json =>

this.setState({

data: [...data, ...json.data],

scrolling: false,

total_pages: json.total_pages

})

);

The result…

Well, it works just fine!

Trigger loadMore with scroll event

For the final part, trigger loadMore on a scroll event.

First, get last <li> with getQuerySelector. Calculate the element offset to get current page offset. If page offset is greater than the Offset of last item that means scrollbar is near the last offset. This should trigger loadMore .

handleScroll = () => {

var lastLi = document.querySelector("ul.container > li:last-child");

var lastLiOffset = lastLi.offsetTop + lastLi.clientHeight;

var pageOffset = window.pageYOffset + window.innerHeight; if (pageOffset > lastLiOffset) {

this.loadMore();

}

};

Bind scroll listeners to the scroll handler.

componentWillMount() {

this.loadUser();

this.scrollListener = window.addEventListener("scroll", e => {

this.handleScroll(e);

});

}

The result:

Great! That’s it. Your component is now ready! You can now use Bit to share it with your team, add it to your component collection and use it anywhere.

Quick Recap

In this post we learned how to implement a React infinite scroll component.

First, we learned how to fetch data from an API, and render it. With loadMore and handleScroll , we calculated the position of the scrollbar. Whenever the scrollbar is near the bottom of the window, fetch more data and append it to the existing data and render the component.

Hope you liked this post, and please feel free to comment and ask any questions! You can also leave me a few 👏 if you liked it. Cheers!