Bootcamp
Search…
7.1: JSX Intro

Introduction

1
const element = <h1>Hello World!</h1>;
Copied!
JSX is a "syntax extension" to JavaScript (JS) that allows us to specify HTML elements directly in JS. We use JSX with React to specify elements we want React to manipulate. This module will walk through the creation of a sample app using JSX.

Setup

Clone Repo

Install Packages

Install React libraries and Babel preset for React.
1
npm install --save-dev react react-dom @babel/preset-react
Copied!

Update Webpack Config to Support React

  1. 1.
    In thewebpack.common.js file, ensure that the test regular expression includes the new file extension, .jsx.
  2. 2.
    Add the React preset to the presets key.
1
{
2
// Regex to decide which files to run Babel on
3
test: /\.(js|mjs|jsx)$/,
4
exclude: /node_modules/,
5
use: {
6
loader: require.resolve('babel-loader'),
7
options: {
8
presets: ['@babel/preset-env', '@babel/preset-react'],
9
},
10
},
11
},
Copied!

Sample Webpack config

The full Webpack common config should look like the following.
webpack_conf/webpack.common.js
1
const HtmlWebpackPlugin = require('html-webpack-plugin');
2
const MiniCssExtractPlugin = require('mini-css-extract-plugin');
3
const path = require('path');
4
​
5
module.exports = {
6
entry: {
7
main: './src/index.js',
8
},
9
output: {
10
filename: '[name]-[contenthash].bundle.js',
11
path: path.resolve(__dirname, '../dist'),
12
// Replace previously-compiled files with latest one on each build
13
clean: true,
14
},
15
plugins: [
16
new HtmlWebpackPlugin({
17
// Name this file main so it does not get automatically requested as a static file
18
filename: 'main.html',
19
template: path.resolve(__dirname, '..', 'src', 'main.html'),
20
}),
21
new MiniCssExtractPlugin(),
22
],
23
module: {
24
rules: [
25
{
26
// Regex to decide which files to run Babel on
27
test: /\.(js|mjs|jsx)$/, // CHANGE HERE: jsx added
28
exclude: /node_modules/,
29
use: [
30
{
31
loader: 'babel-loader',
32
options: {
33
// CHANGE HERE: ensure @babel/preset-react
34
presets: ['@babel/preset-env', '@babel/preset-react'],
35
},
36
},
37
],
38
},
39
{
40
test: /\.scss$/,
41
use: [MiniCssExtractPlugin.loader, 'css-loader', 'sass-loader'],
42
},
43
],
44
},
45
};
Copied!

JSX Syntax

Below is a comparison between how a div with inner text is created using DOM, React, and JSX syntax respectively. While React can be written without using JSX, as seen in the example below, we will be writing React code using JSX syntax, combining the best of React with JSX. React without JSX is for nuanced purposes that we are not addressing in this course.
Try running the JSX code in your Chrome DevTools - there will a syntax error.
Babel is used in the Webpack config to help automatically transform JSX to React.
Note that @babel/preset-env needs to be specified before @babel/preset-react so that ES6 gets transformed to ES5 before JSX gets transformed to React.
1
presets: ['@babel/preset-env', '@babel/preset-react'],
Copied!

DOM JavaScript

1
const myEl = document.createElement('div');
2
myEl.innerText = 'Hey Wow!';
Copied!

React JavaScript

1
const myEl = React.createElement('div', null, 'Hey Wow!');
Copied!

JSX

1
const myEl = <div>Hey Wow!</div>;
Copied!

Minimal JSX App

We are rendering a div element using React and JSX.
We typically set up React in index.js using React's imported createRoot function to create a root component from a root DOM element. We render the React app inside the root component with rootComponent.render.
src/index.js
1
import React from 'react';
2
import { createRoot } from 'react-dom/client';
3
import './styles.scss';
4
​
5
// Create JSX element and log it.
6
const myEl = <div>Hey Wow!</div>;
7
console.log('myEl: ', myEl);
8
​
9
// Create root element to render other elements into, add root element to DOM.
10
const rootElement = document.createElement('div');
11
document.body.appendChild(rootElement);
12
​
13
// Create React root component with root DOM element
14
const rootComponent = createRoot(rootElement);
15
​
16
// Render the myEl JSX element in the root component
17
rootComponent.render(myEl);
Copied!
Run the watch command to have Webpack auto-compile our code.
1
npm run watch
Copied!
Run our Express server in a new terminal to serve our website.
1
npx nodemon index.mjs
Copied!
Visit http://localhost:3004/home in Chrome to view our element.

Using CSS Classes with React

In JSX and React, HTML elements can't have a class attribute because the HTML class keyword conflicts with JavaScript's class keyword. JSX has chosen to replace class with className. React will translate className to class such that our browsers know what CSS to apply.
To add CSS styles to a React app, import a CSS file like in the following code sample. The following code assumes there is a CSS class hero-text defined in ./styles.css.
1
import './styles.css';
2
​
3
const myEl = <div className="hero-text">Hey Wow!</div>;
Copied!

JSX with Multiple HTML Elements

So far we've used JSX to create a single HTML element and rendered that element onto our page. Our equivalent DOM code would be the same length or shorter. The real benefit of JSX is the ability to specify a set of nested elements in the same way we would write HTML. How many lines would the equivalent DOM code be?
There are a couple of rules when writing longer JSX:
  1. 1.
    Surround multi-line JSX expressions with parentheses ().
  2. 2.
    Each JS variable contains at most 1 JSX element. Note the myEl variable contains a single element (c.f. below: a single <div></div> tag as the parent) even though it has other elements inside it.
src/index.js
1
import React from 'react';
2
import { createRoot } from 'react-dom/client';
3
​
4
// Create JSX element and log it.
5
const myEl = (
6
<div>
7
<h1 className="hero-text">
8
Hey <span className="warning">Wow!</span>
9
</h1>
10
<p>Lorem Ipsum!!</p>
11
</div>
12
);
13
console.log('myEl: ', myEl);
14
​
15
// Create root element to render other elements into, add root element to DOM.
16
const rootElement = document.createElement('div');
17
document.body.appendChild(rootElement);
18
​
19
// Create React root component with root DOM element
20
const rootComponent = createRoot(rootElement);
21
​
22
// Render the myEl JSX element in the root component
23
rootComponent.render(myEl);
Copied!

JSX Templating with Data

Basic Templating Example

It is possible to inject JS variables into JSX, similar to how we injected JS variables into EJS. EJS uses <%= %> syntax; JSX uses {}.
In the following example, we initialise a number on line 4 and use it on line 12.
src/index.js
1
import React from 'react';
2
import { createRoot } from 'react-dom/client';
3
​
4
const myRandomNum = Math.random();
5
​
6
// Create JSX element and log it.
7
const myEl = (
8
<div>
9
<h1 className="hero-text">
10
Hey <span className="warning">Wow!</span>
11
</h1>
12
<p>Random Value: {myRandomNum}</p>
13
</div>
14
);
15
console.log('myEl: ', myEl);
16
​
17
// Create root element to render other elements into, add root element to DOM.
18
const rootElement = document.createElement('div');
19
document.body.appendChild(rootElement);
20
​
21
// Create React root component with root DOM element
22
const rootComponent = createRoot(rootElement);
23
​
24
// Render the myEl JSX element in the root component
25
rootComponent.render(myEl);
Copied!

Templates Accept Any JS Code

Curly braces in JSX can contain any valid JavaScript code.
1
const myEl = (
2
<div>
3
<h1 className="hero-text">
4
Hey <span className="warning">Wow!</span>
5
</h1>
6
<p>Random Value: {Math.random() * 100}</p>
7
</div>
8
);
Copied!

Template Substitution Also Works in Element Attributes

JSX also allows templating of HTML attribute values, not just HTML element contents. We need not specify quotations around HTML attribute values. In the following example we initialise a URL string, myUrl, on line 1 and use it in an href attribute on line 7.
1
const myUrl = 'http://google.com';
2
const myEl = (
3
<div>
4
<h1 className="hero-text">
5
Hey <span className="warning">Wow!</span>
6
</h1>
7
<a href={myUrl}>Random Value: {Math.random() * 100}</a>
8
</div>
9
);
Copied!

Further Reading

Read more about JSX on the official docs: https://reactjs.org/docs/introducing-jsx.html​

Exercise

Replicate the above code.