React for WordPress Developers – The Ultimate Guide

The Block Editor (Gutenberg) is built on React. So it is highly recommended to use React in order to create custom blocks (though it is not mandatory). You don’t need to become an expert, but you should have sufficient knowledge of React.

React is the one of three most popular modern Javascript frameworks today. The other two are Angular and Vue JS. React is probably the most popular. It is a Facebook open-source project.

Actually, React is rather a library than a framework. “A JavaScript library for building user interfaces”. The building block of the user interface is the Component.

React Components are UI reusable pieces (eg buttons, header, navigation, sidebar, divs with specific design and functionality). React Components can be nested. A Component can contain one or more Components, and so on.

React keeps a Virtual DOM in memory. So, it makes changes, not to the whole DOM but only where needed. This is the reason why React is impressive and fast.

React provides JSX as an easy way to write (complex) HTML in Javascript code. Another way could be template literals in ES6. However, JSX is much more powerful, as, actually is Javascript which “looks like” HTML. JSX stands for JavaScript XML (eXtensible Markup Language).

But the browser cannot understand React or JSX. The browser can understand Javascript. So you need a tool to convert JSX (in the src folder) to Javascript (in the build folder).

This is the official way to create a React app:

npx create-react-app my-app
cd my-app
npm start

This will install the package react-scripts. It uses webpack, Babel, ESLint, and other great tools to compile JSX to JAVASCRIPT and improve your daily work.

Read details here: Create React App.

WordPress implements React in its back-end (Gutenberg editor) in an excellent way. However, you can write pure React components in the website front end if needed (if you need more interactive pages and not only static content).

You do not need to create a React app (as mentioned above). WordPress offers its own version of react-scripts, named @wordpress/scripts. You only need to run:

npm install @wordpress/scripts --save-dev
npm run start

Read details in this post: How To Write JS and CSS in WordPress with Industry Standard Tools

Get React version

npm view react version

Differences from a classic web project

In a classic web application, we have:

  1. HTML (it calls the CSS and Javascript files with <link> and <script> tags)
  2. CSS
  3. Javascript

In React, we have

  1. Javascript (it imports the CSS or SCSS and other JS files (“modules“) – you can write HTML here as JSX)
  2. CSS or SCSS

JSX

These are the main characteristics of JSX syntax:

ONE root tag

In JSX can only be one sort of root-level element.

This is not valid JSX

<h1>Test header</h1>
<p>Test paragraph</p>

This is valid

<div>
    <h1>Test header</h1>
    <p>Test paragraph</p>
</div>

This is also valid (using React fragment)

<React.Fragment>
    <h1>Test header</h1>
    <p>Test paragraph</p>
</React.Fragment>

or, even better, use the short syntax

<>
    <h1>Test header</h1>
    <p>Test paragraph</p>
</>

As you can guess, JSX elements must either have a matching closing tag or a self-closing tag.

() for multiline

Use () for multiline JSX. It is not needed for single-line statements.

{} for any dynamic

Use curly brackets {} for dynamic expressions and events

Inline styling

<div style={{ backgroundColor: props.attributes.bgColor }}>

Events

<input type="text" onChange={myHandlerFunction} />

Iterations (Loops)

There are no iteration statements available within JSX.

Use array.map or array.filter.

Example:

return (
	<ul>
		{customers.map(customer => (
		<li>{customer}</li>
		))}
	</ul>
);

Conditional statements

There are no conditional statements available within JSX.

Use ternary operator

<div className={"class1" + (myCondition ? " class2" : "")}>

or

{condition && (
 JSX here
)}

Using the above syntax, your JSX will be rendered only if the condition returns true.

camelCase HTML attributes

Use camelCase syntax in HTML attributes like in Javascript (events, CSS, etc). Remember, JSX is Javascript “pretending” it is HTML.

className instead of class – see Element.className

<div className="my-class">

backgroundColor instead of background-color

<p style={{ backgroundColor: "red" }}>

onClick instead of onclick

<button onClick={myFunction}>

Comments

Use curly braces.

{/* Single line comment */}

or

{/* Multi
line
comment */}

Component

A Component can be

  • a Javascript function (Functional Component) or
  • a Javascript Class (Class Component)

All React component names must start with a capital letter.

A functional component

  • accepts arguments (props)
  • returns JSX

A class component

  • extends React.Component
  • has a method render() which returns JSX

Which one to prefer? Functional components or Class components?

SHORT ANSWER: you should use functional components with hooks.

(see below about hooks)

Props

Props are the arguments passed to a functional component. Example:

file MyComponent.js

/**
 * Functional React Component to display a simple message
 *
 * @param {*} props - The component attributes
 * @returns {string} - The component html
 */
export function MyComponent(props) {
    return (
        <div className="my-class">
            <p>{props.message}</p>
        </div>
    );
}

Example code to display a message:

file myapp.js

import React from "react";
import ReactDOM from "react-dom";
import { MyComponent } from "./MyComponent";

Example code to display a message:

const myBlockDivs = document.getElementsByClassName("my-block-instance");

for (const div of myBlockDivs) {
    ReactDOM.render(<MyComponent message="Hello World!"} />, div);
}

Just for reference, if the above functional component was a class component, it would look like this:

class MyComponent extends React.Component {
  render() {
    return (
        <div className="my-class">
            <p>{this.props.message}</p>
        </div>
    );
  }
}

State

The state is a React object that contains data about the component. Whenever it changes, the component re-renders.

In React we DO NOT change component appearance directly (show/hide, add/remove class, etc). We change the state in response to event handlers or props changes. In this case, React re-renders the component.

The state is defined in the constructor for Class Components. You can change it using setState() method.

In functional components, you have to use useState() hook (see below)

Hooks

useState

useState returns an array with two items:

  • the first item is a variable representing this state (a stateful value)
  • the second is a function to update this state
import { useState } from "react";


function MyComponent() {
    const [isPaid, setIsPaid] = useState(false);

    return (
        <>
            <div className={"some-class" + (true === isPaid ? " class-is-paid" : " class-is-unpaid")}>
                Invoice number X
            </div>
            <button type="button" onClick={() => setIsPaid(true)}>Pay invoice X</button>
        </>
    );
}

See alse API reference.

useEffect

It accepts a function that will run under certain conditions (state changes or prop changes).

Read useEffect – See alse API reference.

useBlockProps (on WordPress)

Read useBlockProps

Build – Deploy

For various types of React apps, read https://create-react-app.dev/docs/deployment

In WordPress, things are much simpler: you only need to deploy the build folder.

React in VSCode

The Visual Studio Code editor supports React.js IntelliSense and code navigation out of the box.

Read the tutorial here.