DEV Community

Cover image for Basic post navigation with React and the WordPress Rest Api.
Stephan Nijman
Stephan Nijman

Posted on • Originally published at since1979.dev

Basic post navigation with React and the WordPress Rest Api.

Originally posted on my website on May 21th 2020

Creating a list of WordPress posts with navigation in React

Lately I've been playing around with React.js and the WordPress Rest Api and in this article I want to share with you some of the basic things i learned.

So in this article we are going to create a very basic App that can fetch posts from the WordPress Rest Api and lets users paginate between different pages of posts.

I'm going to assume that you at least know the basics of React. And that you already have bare-bone React app setup because I'm not going to handle that in this article. Please refer to the Sand Box below above if you want to see how I set this up.

Sandbox

I have a Code Sand Box setup here with a working version of what we are going to created so you can check it out and also grab the styles to make it look a bit more presentable

Fetching posts and rendering the list

Some local state

To get started we need some local state to store the post data we get back from the Api.

To do so we use the useState hook to create some local state to hold out posts and a setPosts function to update this state. We also default it to an empty array.

Fetching the posts

Now that we have some state we can fill it with posts from the WordPress Rest Api.

To get the posts from the Api we use the useEffect hook to run when our component gets mounted and then we use Axios to make the actual Api request.

To get our first list of the ten latest posts we can simply call the /wp-json/wp/v2/posts end-point. When the requests returns we simply store the date using the setPosts function we created.

Rendering the posts

Now that we have a list of posts to work with we can render them.

Here we first render a wrapper div and a little title for our app. Inside this div we create another div to wrap our list of posts.

Then we do a check to see if our posts lists gives a true-thy value and if it has more then 0 values, meaning it is no longer an empty array.

We then use the Array.map higher order function to loop over out posts list and render out a div containing the posts data we want to show.

We render a h2 tag with the post title. We then use dangerouslySetInnerHTML to render the excerpt because the Api returns an Html p tag containing the excerpt and React doesn't allow us to render plain Html. lastly we create an *a*nchor tag with a link to the post.

Note that we append .rendered to the title and the excerpt. It looks a bit silly because the Api doesn't return an un-rendered version but it is what it is!

Adding post navigation

Thus far we are only displaying the latest ten posts but it would be nice if our users can paginate to older posts and back as well. So lets add that to our little app.

Page and Nrofpage state

By default the WordPress Rest Api divides our posts into "pages" containing ten posts each. We could change that number but in this case we will stick to the default ten.

To keep track of the current page and the maximum number of pages we need to create some more local state.

In the code snippet above we use the setState function to create some state for the current page, default it to 1 since there is no page 0, and a function called setPage to change this value. we also create state for nrofpages, default that to 1 also and a setNumberofpage function to change this state as well.

Adjusting the useEffect function

Now we need to pass the page number to the Rest Api, and also get the max number of pages from the initial response.

First we add our page state to the dependency list for our useEffect function so it will not only run when our component gets mounted but also when the value of page changes.

Then we pass an extra object to our Axios.get function being an object with a key of params, and set that to another object containing the data we want to send to the Api.

In this case we need to send the page number we want to retrieve. so we add a key value pair for page and set that to the value of our page state we created.

When our request gets back we now also grab the max number of pages from the response headers with response.headers["x-wp-totalpages"]. And add that to our nrofpages state using our setNumberofpage function.

Adding event handlers

To be able to switch between pages we need some buttons for "newer posts" and "older posts". but first we need some event handlers for when these buttons get clicked.

First we create a function called handlePrevPage and use it to decrement our page state by 1 using our setPage function. But we use a ternary operator to first check if page -- 1 results in a true-thy value, meaning it must be 1 or higher. if it is we can decrement by 1 else we just set it to be 1 since that is the lowest possible page number.

We also add a handleNextPage function which does almost the same but now we need to increment by 1 and check if the page state doesn't exceed the maximum number of pages if it does we just set it to nrofpages.

Rendering the navigation

With our event handlers in place we can render out a little navigation above our posts list.

Here we render another wrapper div above our posts list, and inside of this div we render two buttons setting their onClick events to thehandlePrevPage and handleNextPage event handler functions we just created.

In between the buttons we also render a p tag with a little indicator of what page the user is currently on.

With all this in place our app now fetches a list of ten posts from the WordPress Rest Api and renders it to the screen. It also allows our users to paginate forward and backwards between the pages of posts.

Completed component

Below is the completed code for our component as a reference. And again I also have a Code Sand Box here with a working version of what we created so you can check it out and also grab the styles to make it look a bit more presentable.

Follow?

Let's connect on twitter @Vanaf1979 or here on Dev.to @Vanaf1979 to be notified about new articles, and other WordPress development related resources.

Thanks for reading and stay safe.

Top comments (4)

Collapse
 
marcomaffei3 profile image
Marco Maffei 🦁

Dear Stephan,

Thank you for this snippet, I've been looking for something similar for a while. I was trying a different approach with fetch or Promise, but I hadn't got lucky until I found your snippet.

I would like to ask you a suggestion about how to change a little bit the code, instead of having a previous and a next button, I would like to create a pagination. I did a project on my github account with the wordpress API and vanilla javascript, but I built in PHP (so essentially I created a query in sql and then I return a json file from it, and I used ajax to retrieve the data and have a super fast pagination of my post, or really any kind of route you can built with the wordpress-api).

I've been using react since a couple of months, and I found it very challenging.

In any case, I would like to change this behavior:



Page {page} of {nrofpages}


I would like to map the nrofpages variable so I can create a markup (

  • ${i}
) but I'm pretty sure it won't work, so I was trying to figure it out what could be the best approach to create a pagination for this component.

If you want to have a look at the plugin that I create for wordpress, here's the link:

github.com/orso081980/Track-email-....

Please let me know what is your thought regarding it and thank you in advance for your answer!

Collapse
 
vanaf1979 profile image
Stephan Nijman

Hey Marco,

Thanks for you kind feedback. :)
As for your Question... Could you send me a DM on Twitter @vanaf1979 ? I might be able to help you out.

Cheers,

Stephan

Collapse
 
rajangupta profile image
Rajan Gupta

Hello Stephan,

How to display featured image.

Image description

Collapse
 
vanaf1979 profile image
Stephan Nijman

Hi Rajan,

I've written an article about that here: since1979.dev/add-custom-acf-field... Scroll down a bit and you will find your answer! :)