React WP theme: Creating dumb components

In today’s post, we will look at Bootstrap blog template and create React dumb components out of it. Nothing too fancy, just some copy pasting and refactoring. After completing the steps in the article, we’ll be ready to create the smart components, plug the dumb ones into them and have a working blog theme!

Tutorial navigation

  1. React single-page WordPress REST API theme tutorial
  2. React WP theme: structure, Node packages and Webpack
  3. React WP theme: Smart vs Dumb components + React Router
  4. React WP theme: Creating dumb components (current)
    .
    . to be written
    .

Breaking down Bootstrap blog theme

The first step is to analyze Bootstrap’s blog theme design and decompose it into logical parts. Let’s have a look at the first figure below:

Figure 1: Bootstrap blog theme — top part
Figure 1: Bootstrap blog theme — top part

From it, we can see that there is a main navigation, header, list of posts and a sidebar. The figure below depicts the bottom part of the theme:

Figure 2: Bootstrap blog theme — bottom part
Figure 2: Bootstrap blog theme — bottom part

This time, there’s a pagination and a footer.

We will create React components according to these observations.

Creating the dumb components

In the previous article, I talked about smart vs dumb React components. To sum it up, it’s basically a division between the controller and the view (for those coming from the MVC world). A React component can contain any kind of logic and presentation as well so it’s a good idea to split it into separate components: the smart ones handle logic (data fetching, computations, transformations) and the dumb ones the presentation of data (HTML).

Firstly, let’s create the dumb components. We’ll place them into the src/components folder.

Header

Create a new file called Header.js in the src/components/ folder. Firstly, we need to import React and Component objects from the package react because both of them will be used throughout the code.

import React, { Component } from 'react';

Now, let’s create a new class called Header which extends from Component:

class Header extends Component {

}

In the first figure, we can see that header is really simple — just two lines of text. That’s why the class will contain only the render() method with some HTML written in the JSX syntax. Here’s the complete file:


import React, { Component } from 'react';
export default class Header extends Component {
render() {
return (
<div className="blog-header">
<div className="container">
<h1 className="blog-title">The Bootstrap Blog</h1>
<p className="lead blog-description">An example blog template built with Bootstrap.</p>
</div>
</div>
);
}
}

view raw

Header.js

hosted with ❤ by GitHub

Footer and Sidebar

Like Header, footer and sidebar are very simple. We just import React, Component and transform HTML into JSX. Here are the files: footer, sidebar. Note: I might update these components in the future so they might not be that simple. In that case, I’ll write a new article describing how to do it.

Facebook has a cool online HTML to JSX transformer. Although I prefer doing it myself, you can also use that for the job.

MainNavigation

Now, something more interesting. Earlier, I showed you how to use React Router with React to implement the basic Routing. But that’s only one part of the puzzle. What about links in the navigation? How should they look like?

As usual, we need to import React and Component. Then, we need to import Link from react-router:

import { Link } from 'react-router';

Link is a React component which renders the <a> element with proper URL address and performs the routing on clicking the link. It also assigns a special class to the element when the link is active (=> we are on the site the link points to). How does it look like?

<Link to="/about" className="nav-link" activeClassName="active">About</Link>

The most important prop is to. It specifies the <Route> which the link will navigate to. In our case, it’s the <Route path="about" component={AboutPageContainer} /> route. Notice that I put the ‘/’ at the beginning of the path — it’s because if I didn’t, the link would just add ‘about’ to the current URL and that would not match any Routes. So, when I click the About link, React will render the AboutPageContainer component, thus “navigating” us to the About page (more details in the following article).

We can use the activeClassName prop to define our own CSS class which React Router will add to the link when it is active.

Here’s the complete MainNavigation.js file:


import React, { Component } from 'react';
import { Link } from 'react-router';
export default class MainNavigation extends Component {
render() {
return (
<div className="blog-masthead">
<div className="container">
<nav className="nav blog-nav">
<Link to="/" className="nav-link" activeClassName="active" onlyActiveOnIndex={true}>Home</Link>
<Link to="/2015/02/some-article" className="nav-link" activeClassName="active">Some Article</Link>
<Link to="/about" className="nav-link" activeClassName="active">About</Link>
</nav>
</div>
</div>
);
}
}

AboutPage

AboutPage.js is a dumb component which takes a page data (title, content, etc) as an input and outputs a page in HTML. This component is very similar to those we talked about before, except one thing — we can’t simply put HTML code into a React component due to security precautions.

A standard page has some text which gets wrapped into paragraphs (<p>) when saved to database. Normally, React disallows us from putting HTML into a React component because it “can open you up to a cross-site scripting (XSS) attack“. Fortunately, there’s an official way to bypass this restriction — but I warn you, you gotta be sure about the HTML/JS code your page has. It could really result in a nasty hack.

To put HTML into React component, we need to write a function first:

createMarkup(html) {
    return {
        __html: html
    }
}

This function takes the (secure) HTML as an input and returns an object containing one key __html (notice the double underscore) with the (secure) HTML as its value. Nothing fancy, just to discourage the programmers who don’t understand the risks.

Now that we have the createMarkup function, creating the AboutPage component is really simple. Here’s the entire code:


import React, { Component } from 'react';
// Dumb component
export default class AboutPage extends Component {
createMarkup(html) {
return {
__html: html
}
}
render() {
const { page } = this.props; // Extract the page from the component's props.
return (
<div className="blog-post">
<h2 className="blog-post-title">{page.title.rendered}</h2>
<div dangerouslySetInnerHTML={this.createMarkup(page.content.rendered)} />
</div>
);
}
}

view raw

AboutPage.js

hosted with ❤ by GitHub

Post

Post.js is mostly the same as AboutPage.js except we also use the post’s date to display it. Link to the component.

Conclusion

We have learned how to create a simple React component with JSX syntax and how to output HTML content in it. In the following article, we’ll create the smart components which will retrieve the data from the WP backend, handle the logic and pagination. Stay tuned!

Join the Conversation

9 Comments

  1. What it can be a problem when I try to run your HitHub project?

    npm ERR! Lexi-WP-Theme@0.0.1 clean: `rm -rf dist`
    npm ERR! Exit status 1
    npm ERR!
    npm ERR! Failed at the Lexi-WP-Theme@0.0.1 clean script ‘rm -rf dist’.
    npm ERR! This is most likely a problem with the Lexi-WP-Theme package,
    npm ERR! not with npm itself.
    npm ERR! Tell the author that this fails on your system:
    npm ERR! rm -rf dist
    npm ERR! You can get their info via:
    npm ERR! npm owner ls Lexi-WP-Theme

    But ! If I’ll clean up scripts in webpack.config.js
    I can see the Theme at http://localhost:3000/

    AND this message on the console

    webpack: bundle is now VALID.

    Like

    1. From the error log, it seems like the command ‘rm’ is not supported on your operating system. You are probably using Windows. I’ll fix this by using the ‘rimraf’ npm package instead of ‘rm’ command.

      Thanks for reporting!

      Like

  2. Very cool tutorial so far! I hope you will add the next pages soon! 🙂 cant wait for the smart components! Thanks for this awesome guide!

    Like

  3. Very curious about the next parts as well, connecting things to WP which is the most interesting part to me. Thanks for writing this!

    Like

Leave a comment

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: