Let’s build a WordPress theme with React: Part 2 (Routes + Context)

Now that we have our react app setup, let’s form how our application will be structured. We’re going to need 3 main folders: 1) templates, 2) partials and 3) context. These are all going to be inside react-src.

The templates folder is where we’re going to store the main files template files – namely Single.js and Archive.js. Single shows a single post, while Archive shows a running list of post in reverse chronological order.

The partials contain bits and pieces of reusable parts. These are files that make up the header, navigaition, pagination and the loop.

The context is where the data sits. We’re going to have two files in here – Context.js and WithConsumer.js. These files are what we need to store state and props. More on this later.

Also, don’t forget that we have our public folder (which is outside the src directory). This contains all the regular PHP files such as functions.php etc.

Routes

Let’s begin by adding a simple route. Make sure we’re in development mode by running:

Let’s create a new component called “Single”. Inside it, let’s start simple and put in the code below:

Pretty basic right? Now let’s install react router by running the command below:

Open up index.js and include react router in it

Inside the render function, let’s modify it to look like this:

Now navigate to your site, but append the path “/page”. You should see your page component rendered.

Now let’s go back to index.js and modify the Route to look like below:

Notice we’re adding a :slug to the path. We’re going to be updating our component with this parameter. The slug will be the actual “slug” of the WordPress post. If you modify our page component with:

You should see something like below:

So by now, you should see how we’re going to continue with our theme. We’re going to be adding the following routes:

  • Home – mapped to “Archive”
  • Page + slug – mapped to “Single”
  • Post + slug – mapped to “Single”
  • Search + term – mapped to “Archive”
  • 404 – mapped to “404”

Go ahead and copy the Single component, duplicate it – and call it “Archive”. Then let’s match it to the routes above.

Our index.js now looks like below:

Partials

Let’s quickly talk about our partials. Partials are components that we will be reusing in each route component. Things that come to mind are header, footer, sidebar – and whichever reusable piece of code we will come across along the way.

Let’s go ahead and create 2 partials. Head.js and Foot.js. These will be the header and footer of our pages. The code will be a simple functional component like below:

Now in our template components, simply import, and add the components in. Here is the how our Single.js will look like with the partials. Note – make sure you add them inside the main div:

In the browser, you will see our partials and home page starting to take shape. Inspect the code and it should look like below:

Do the same thing to the rest of our main components so they all share the same header and footer.

Context (Data)

As mentioned above, this is where our data will sit. React has Context API which allows you to have a centralized data store – so that you don’t have to pass data through each child component. This article is probably the best explanation on Context API. As a matter of fact, the two files that we’re going to build, is code that came from the article.

Let’s start with Context.js. This file is considered to be the “Provider“. Add the code below:

Don’t worry so much about the test posts data. We’re just using that for – well, testing. Then let’s create WithConsumer.js

Now this one is pretty confusing. It’s basically a wrapper – for our components that require the “Consumer” component. Basically, all our components that want to “consume” data from our “Provider” will be using this file.

Now let’s create a partial called “TheLoop“. Add the code below:

Notice that in our export – we’re passing our component TheLoop as a parameter to WithConsumer.

We’re going to talk more in detail about TheLoop component in our next session. For now, we just want to get it up and running – to demonstrate Context and Consumer.

Let’s open Single.js from our templates folder and modify it to look like this:

You see how we’re wrapping everything in “<Provider>“, this is so we have access to our Context.js data. Also, we’ve included “TheLoop” as a component in between Head and Foot.

You should see “title” and “title2” in the browser by now.

Lastly, we need a way to get our “slug” parameter into our context. We can use props for that. Still in Single.js, pass the slug via props like so:

In Context.js, we should have access to the slug – through “props.router.match.params.slug“. As a matter of fact, we have access to the entire router object here, in a prop called “router”.

Let’s stop here for now. We are going to discuss more about TheLoop and Axios in our next session.

14 Comments

  1. I did all like in examples, was couple mistakes in code, but after couple of hours i fixed it, but still was the problem when I try to create post with permalink example.com/post/some-new-post and I fixed it with plugin Permalink Manager Lite. Maybe for someone will be useful my comment. Thank you Michael for article.

    Reply
  2. As soon as I created the folders “templates”,”partials”,”context” in the barebones/react-src. and run the command “npm run wpstart”
    Everything stops working.

    Reply
    • Yes – I’ve been too busy these days working on another project. The theme is done, but the tutorial I will finish it soon. Sorry about that.

      Reply
  3. I have copied the code above exactly and for some reason react router dom does not seem to work.I have even copied and pasted the code onto another react project that is not on wordpress and the router works, so this makes me think there is something else that needs to be set up for it to work properly with wordpress. Perhaps something to do with permalinks or .htaccess?

    In detail, it would seem that path=”/” or no specified path work, but I cannot use “exact” or have any path that is more than “/”, therefore “/path” doesn’t work.

    Is there something I have missed out to get this to work in terms of setup? Please help!

    Reply
      • Hi there,

        Thanks for the response, but yes this was all without the “exact” attribute initially, its just its literally anything that is more than “/” and even the exact doesnt work, so literally nothing works.

        I will look through your code to see if im missing anything

Leave a Comment.