Get Started with Modern React: Step by Step
S02・V04: Introducing JSX
- We will examine JSX in more detail.
- We will show examples of how JSX is used in React.
JSX
JSX is a syntax extension to JavaScript. Using JSX with React is recommended to describe what the UI should look like. JSX compiles to React element
s, which we discussed in the previous video. We can comment out our header element
on line 6, and uncomment the JSX version in the line above.
import React from "react";
import ReactDOM from "react-dom";
const rootNode = document.getElementById("root");
const element = <h1>Hello, World!</h1>;// const element = React.createElement("h1", {id: "header"}, "Hello, World!");
ReactDOM.render(element, rootNode);
JSX Props
Now, the element
we created in line 6 has a props
object, with an id
of header
. One way to add props to a JSX element is to specify a string literal as an attribute to the tag. In our example, we can add an id
attribute, with a value of header
as a string literal.
import React from "react";
import ReactDOM from "react-dom";
const rootNode = document.getElementById("root");
const element = <h1 id="header">Hello, World!</h1>;// const element = React.createElement("h1", {id: "header"}, "Hello, World!");
ReactDOM.render(element, rootNode);
We can see that our red header color has been successfully applied.
Since JSX is closer to JavaScript than HTML, we camel-case attribute names in JSX. For example, the global HTML attribute contenteditable
is written all lower-case, but in JSX, we camel-case the prop contentEditable
.
import React from "react";
import ReactDOM from "react-dom";
const rootNode = document.getElementById("root");
const element = <h1 id="header" contentEditable>Hello, World!</h1>;// const element = React.createElement("h1", {id: "header"}, "Hello, World!");
ReactDOM.render(element, rootNode);
Now our header is editable. Let’s now remove the contentEditable
and id
attributes, and delete the commented out line.
import React from "react";
import ReactDOM from "react-dom";
const rootNode = document.getElementById("root");
const element = <h1>Hello, World!</h1>;
ReactDOM.render(element, rootNode);
Now, let’s go to public/index.html
and remove the styles.
<!DOCTYPE html>
<html lang="en">
<head>
<title>React App</title>
</head>
<body>
<div id="root"></div>
</body>
</html>
Embedding Expressions in JSX
Now, we will return to src/index.js
. We can embed JavaScript expressions within JSX. Define a constant name
with the value of the string literal John Doe
. Instead of the word World
in our header, we can embed the name
within the JSX element, within curly braces.
import React from "react";
import ReactDOM from "react-dom";
const name = "John Doe";const rootNode = document.getElementById("root");
const element = <h1>Hello, {name}!</h1>;
ReactDOM.render(element, rootNode);
We can put any valid JavaScript expression inside the curly braces in JSX. For example, we can call a function. Let’s define the function formatName()
. It will return the user’s first name
and last name
. Now, we will add some user
data. It will be an object with fields for the first name
, last name
, and photoUrl
.
import React from "react";
import ReactDOM from "react-dom";
function formatName(user) { return `${user.firstName} ${user.lastName}`;}
const user = { firstName: "Jane", lastName: "Roe", photoUrl: "https://picsum.photos/id/1027/200/100"};
const rootNode = document.getElementById("root");
const element = <h1>Hello, {formatName(user)}!</h1>;
ReactDOM.render(element, rootNode);
JSX is an Expression Too
Note that after compilation, JSX expressions become regular JavaScript function calls and evaluate to JavaScript objects. This means that you can use JSX inside of if
statements and for
loops, you can assign JSX to variables, accept JSX as arguments, and return JSX from functions.
Let’s define a function that gets a greeting for a user
.
If there is a user
, then return a greeting using their formatted name.
Otherwise, return a generic greeting.
import React from "react";
import ReactDOM from "react-dom";
function formatName(user) {
return `${user.firstName} ${user.lastName}`;
}
const user = {
firstName: "Jane",
lastName: "Roe",
photoUrl: "https://picsum.photos/id/1027/200/100"
};
function getGreeting(user) { if (user) { return `Hello, ${formatName(user)}!`; } return `Hello, Stranger.`;}
const rootNode = document.getElementById("root");
const element = <h1>{getGreeting(user)}</h1>;
ReactDOM.render(element, rootNode);
Now, let’s see what happens when we set our user
to null
.
const user = null;
We see our page now shows Hello, Stranger.
. Now that we have illustrated that, let’s undo setting user
to null
.
Self-Closing JSX Tags
If a tag is empty, you may close it immediately, as you would do in XML
. For example, an img
tag is closed immediately.
import React from "react";
import ReactDOM from "react-dom";
function formatName(user) {
return `${user.firstName} ${user.lastName}`;
}
const user = {
firstName: "Jane",
lastName: "Roe",
photoUrl: "https://picsum.photos/id/1027/200/100"
};
function getGreeting(user) {
if (user) {
return `Hello, ${formatName(user)}!`;
}
return `Hello, Stranger.`;
}
const rootNode = document.getElementById("root");
// const element = <h1>{getGreeting(user)}</h1>;const element = <img src={user.photoUrl} />;
ReactDOM.render(element, rootNode);
Specifying Children with JSX
Instead of using quotes to specify string literals as attributes, you can also use curly braces to embed a JavaScript expression in an attribute. JSX tags may contain several children.
const element = ( <div> <h1>{getGreeting(user)}</h1> <img src={user.photoUrl} /> </div>);
JSX Prevents Injection Attacks
As a final point for this video, JSX prevents injection attacks. It is safe to embed user input in JSX. To demonstrate this, let’s first remove the element
s we have used up to now. We can also remove the function declarations and the user
. Now, let’s prompt the user for some input, which if the user is a hacker, could be malicious code. And, we will create an element
embedding the user input received.
import React from "react";
import ReactDOM from "react-dom";
const potentiallyMaliciousUserInput = prompt();
const element = <div>{potentiallyMaliciousUserInput}</div>;const rootNode = document.getElementById("root");
ReactDOM.render(element, rootNode);
Now, we can try to enter a script which is malicious in the prompt input field in Google Chrome:
<script>alert('malicious attack')</script>
By default, React DOM escapes any values embedded in JSX before rendering them. Thus it ensures that you can never inject anything that’s not explicitly written in your application. Everything is converted to a string before being rendered. This helps prevent XSS
attacks.
Summary
We had a close look at JSX, and we showed several examples of how it is used with React.
Next Up…
In the next video, we will show you how to render React elements to the DOM, and update them.