How to build a Load More button in React

Adebola Adeniran
4 min readJun 30, 2020

--

We’re building a loadmore button that will load and show more posts each time we click loadmore.

I’ll show you a simple way using a for loop and then a more efficient way by concatenating arrays.

Create a new React project using Create-react-app

npx create-react-app loadmore && cd loadmore

Get the posts data

  1. Copy the first 10 posts from here
  2. Create a postsArray.js file inside our src folder and paste the posts in here. Assign the array of posts to a posts variable. Like below. I’m hiding the other 9 posts here, but you should have a total of 10posts.
    Finally, export the posts.

3. Now import these posts inside your <App /> component.

Create a Posts Component

4. Next create a Posts component. This component will be responsible for displaying all our posts on the screen. It’ll take a prop of postsToRender. This will be all the posts to be displayed. See below.

import React from "react";const Posts = ({ postsToRender }) => {return (
<ul>
{postsToRender.map((post, index) => (
<li key={index}>
<strong>{post.id}</strong>
&nbsp;{post.title}
</li>
))}
</ul>
);
};
export default Posts;

Now Import this component into <App />

Build the logic for the Load more Button

5. Now, head to App.js. We need to specify the number of posts we want to show on each page. For this tutorial we’ll show 3. Let’s define a variable called postsPerPage and assign 3 to it. Let’s also declare an empty array called arrayForHoldingPosts . This array will hold our posts just before we display them.

Finally, create the load more button and pass it an onclick handler of handleShowMorePosts .

Let’s also bring in useState and useEffect. Our App component will now look like below.

import React, { useState, useEffect } from "react";import Posts from "./Posts";
import posts from "./postsArray";
const postsPerPage = 3;
const arrayForHoldingPosts = [];
const App = () => {
return (
<div>
<Posts />
<button onClick={handleShowMorePosts}>Load more</button>
</div>
);
};
export default App;

6. Now let’s create states for our counter and the array we want to display on the page. Our counter will increase each time the load more button is clicked and populate arrayForHoldingPosts. We will then using arrayForHoldingPosts to set the state of the posts we want to show postsToShow.

const [postsToShow, setPostsToShow] = useState([]);
const [count, setCount] = useState(1);

Now, let’s define a function that loops through the posts, pushes each post to our arrayForHoldingPosts and then sets the state of postsToShow to this array.

const loopThroughPosts = (count) => {
for (
let i = count * postsPerPage - postsPerPage;
i < postsPerPage * count;
i++
) {
if (posts[i] !== undefined) {
arrayForHoldingPosts.push(posts[i]);
}
}
setPostsToShow(arrayForHoldingPosts);

};

7. Let’s define our useEffect and handleShowMorePosts function.

For our useEffect — When the page loads, we want to immediately add 1 to the count. If we don’t do this, we will end up with a stale value and our count state will not update immediately when we click the load more button.

for our handleShowMorePosts — Each time the user clicks load more, we will increase the value of count then use that value to loopThroughPosts and decide what parts of the data to display.

Here’s our useEffect and handleShowMorePosts.

// load the first set of posts when the page loads
// and then set the value of count to 2
useEffect(() => {
setCount((prevCount) => prevCount + 1);
loopThroughPosts(count);
}, []);
const handleShowMorePosts = () => {
setCount((prevCount) => prevCount + 1);
loopThroughPosts(count);
};

8. Lastly pass the postsToShow as a prop to the Posts component postsToRender.

Here’s the full code for the App component now.

import React, { useState, useEffect } from "react";import Posts from "./Posts";
import posts from "./postsArray";
const postsPerPage = 3;
const arrayForHoldingPosts = [];
const App = () => {
const [postsToShow, setPostsToShow] = useState([]);
const [count, setCount] = useState(1);
const loopThroughPosts = (count) => {
for (
let i = count * postsPerPage - postsPerPage;
i < postsPerPage * count;
i++
) {
if (posts[i] !== undefined) {
arrayForHoldingPosts.push(posts[i]);
}
}
setPostsToShow(arrayForHoldingPosts);

};
// load the first set of posts when the page loads
// and then set the value of count to 2
useEffect(() => {
setCount((prevCount) => prevCount + 1);
loopThroughPosts(count);
}, []);
const handleShowMorePosts = () => {
setCount((prevCount) => prevCount + 1);
loopThroughPosts(count);
};
return (
<div>
<Posts postsToRender={postsToShow} />
<button onClick={handleShowMorePosts}>Load more</button>
</div>
);
};
export default App;

Now, when you click load more, your page is automatically populated with the next set of posts.

A more efficient way

A better way to solve this problem is to concatenate arrays and use the useRef hook. We can use the ES6 spread operator to achieve this. It’ll also make our code way shorter.

import React, { useState, useEffect, useRef } from "react"
import Posts from "./Posts"
import posts from "./postsArray"
const App = () => {
const [postsToShow, setPostsToShow] = useState([])
const postsPerPage = 3
let arrayForHoldingPosts = []
const ref = useRef(postsPerPage)
const loopWithSlice = (start, end) => {
const slicedPosts = posts.slice(start, end)
arrayForHoldingPosts = arrayForHoldingPosts.concat(slicedPosts)
setPostsToShow(arrayForHoldingPosts)
}
useEffect(() => {
loopWithSlice(0, postsPerPage)
}, [])
const handleShowMorePosts = () => {
loopWithSlice(ref.current, ref.current + postsPerPage)
ref.current += postsPerPage
}
return (
<div>
<Posts postsToRender={postsToShow} />
<button onClick={handleShowMorePosts}>Load more</button>
</div>
)
}
export default App

Read more posts like this on my blog.

--

--

Adebola Adeniran

Chief of Staff at Moni (YC W22) | Developer Advocate Building on Tezos