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:
In React, we have
- Javascript (it imports the CSS or SCSS and other JS files (“modules“) – you can write HTML here as JSX)
- 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.
Entrepreneur | Full-stack developer | Founder of MediSign Ltd. I have over 15 years of professional experience designing and developing web applications. I am also very experienced in managing (web) projects.