JSX

Before going into JSX lets enumerate the main reasons why people choose to program with React.

Why React?

React.js is a JavaScript library. It was developed by engineers at Facebook. Here are just a few of the reasons why people choose to program with React:

  • React is fast. Apps made in React can handle complex updates and still feel quick and responsive.
  • React is modular. Instead of writing large, dense files of code, you can write many smaller, reusable files. React’s modularity can be a beautiful solution to JavaScript’s maintainability problems.
  • React is scalable. Large programs that display a lot of changing data are where React performs best.
  • React is flexible. You can use React for interesting projects that have nothing to do with making a web app. People are still figuring out React’s potential. There’s room to explore.
  • React is popular. While this reason has admittedly little to do with React’s quality, the truth is that understanding React will make you more employable.

If you are new to React, then this course is for you! No prior React knowledge is expected. We will start at the very beginning and move slowly. The only prerequisite is JavaScript. 

Hello World

Take a look at the following line of code:

const h1 = <h1>Hello world</h1>;

 

What kind of weird hybrid code is that? Is it JavaScript? HTML? Or something else?

It seems like it must be JavaScript, since it starts with const and ends with ;. If you tried to run that in an HTML file, it wouldn’t work.

However, the code also contains <h1>Hello world</h1>, which looks exactly like HTML. That part wouldn’t work if you tried to run it in a JavaScript file.

What’s going on? Does this code belong in a JavaScript file, an HTML file, or somewhere else?

The answer is…a JavaScript file! Despite what it looks like, your code doesn’t actually contain any HTML at all.

The part that looks like HTML, <h1>Hello world</h1>, is something called JSX.

What is JSX?

JSX is a syntax extension for JavaScript. It was written to be used with React. JSX code looks a lot like HTML.

What does “syntax extension” mean?

In this case, it means that JSX is not valid JavaScript. Web browsers can’t read it!

If a JavaScript file contains JSX code, then that file will have to be compiled. That means that before the file reaches a web browser, a JSX compiler will translate any JSX into regular JavaScript.

JSX Elements

A basic unit of JSX is called a JSX element.

Here’s an example of a JSX element:

<h1>Hello world</h1>

 

This JSX element looks exactly like HTML! The only noticeable difference is that you would find it in a JavaScript file, instead of in an HTML file.

Try on your computer

Create a file named index.html in your desktop and enter this code there:

 

<!DOCTYPE html>
<html>
<head>
  <script src=“https://unpkg.com/react@16/umd/react.development.js”></script>
  <script src=“https://unpkg.com/react-dom@16/umd/react-dom.development.js”></script>
  <script src=“https://unpkg.com/@babel/standalone/babel.min.js”></script>
</head>
<body>
  <div id=“root”></div>
  <script type=“text/babel”>     
      const helloWorld = <h1>Hello world</h1>
      ReactDOM.render(helloWorld,document.getElementById(“root”));
    </script>
</body>
</html>

 

Open index.html in your browser to see `Hello World` in the web page. 

 

Throughout this lesson edit this file and check results in the browser. When you define a variable to have a JSX code, use same name in the ReactDOM.render method, like helloWorld in above code.

Do not worry if you do not know the meaning of the above code, you will find out soon in Rendering JSX section.

JSX Elements And Their Surroundings

JSX elements are treated as JavaScript expressions. They can go anywhere that JavaScript expressions can go.

That means that a JSX element can be saved in a variable, passed to a function, stored in an object or array…you name it.

Here’s an example of a JSX element being saved in a variable:

const navBar = <nav>I am a nav bar</nav>;

 

Here’s an example of several JSX elements being stored in an object:

const myTeam = {
  center: <li>Benzo Walli</li>,
  powerForward: <li>Rasha Loa</li>,
  smallForward: <li>Tayshaun Dasmoto</li>,
  shootingGuard: <li>Colmar Cumberbatch</li>,
  pointGuard: <li>Femi Billon</li>
};

Attributes In JSX

JSX elements can have attributes, just like HTML elements can.

A JSX attribute is written using HTML-like syntax: a name, followed by an equals sign, followed by a value. The value should be wrapped in quotes, like this:

my-attribute-name=“my-attribute-value”

 

Here are some JSX elements with attributes:

<a href=“http://www.example.com”>Welcome to the Web</a>;

const title = <h1 id=”title”>Introduction to React.js: Part I</h1>;

 

A single JSX element can have many attributes, just like in HTML:

const panda = <img src=“images/panda.jpg” alt=“panda” width=“500px” height=“500px” />;

Nested JSX

You can nest JSX elements inside of other JSX elements, just like in HTML.

Here’s an example of a JSX <h1> element, nested inside of a JSX <a>element:

<a href=“https://www.example.com”><h1>Click me!</h1></a>

 

To make this more readable, you can use HTML-style line breaks and indentation:

<a href=“https://www.example.com”>
  <h1>
    Click me!
  </h1>
</a>

 

If a JSX expression takes up more than one line, then you must wrap the multi-line JSX expression in parentheses. This looks strange at first, but you get used to it:

(
  <a href=“https://www.example.com”>
    <h1>
      Click me!
    </h1>
  </a>
)

 

Nested JSX expressions can be saved as variables, passed to functions, etc.,  just like non-nested JSX expressions can! Here’s an example of a nested JSX expression being saved as a variable:

const theExample = (
  <a href=“https://www.example.com”>
    <h1>
      Click me!
    </h1>
  </a>
);

JSX Outer Elements

There’s a rule that we haven’t mentioned: a JSX expression must have exactly one outermost element.

In other words, this code will work:

const paragraphs = (
  <div id=“i-am-the-outermost-element”>
    <p>I am a paragraph.</p>
    <p>I, too, am a paragraph.</p>
  </div>
);

 

But this code will not work:

const paragraphs = (
  <p>I am a paragraph.</p>
  <p>I, too, am a paragraph.</p>
);

 

The first opening tag and the final closing tag of a JSX expression must belong to the same JSX element!

It’s easy to forget about this rule, and end up with errors that are tough to diagnose.

If you notice that a JSX expression has multiple outer elements, the solution is usually simple: wrap the JSX expression in a <div></div>.

Rendering JSX

You’ve learned how to write JSX elements! Now it’s time to learn how to render them.

To render a JSX expression means to make it appear on screen.

ReactDOM.render(<h1>Hello world</h1>, document.getElementById(‘app’));

 

Let’s examine the code that you just wrote. on line 5, all the way to the left.

You can see something called ReactDOM. What’s that?

ReactDOM is the name of a JavaScript library. This library contains several React-specific methods, all of which deal with the DOM in some way or another.

We’ll talk more later about how ReactDOM got into your file. For now, just understand that it’s yours to use.

Move slightly to the right, and you can see one of ReactDOM‘s methods: ReactDOM.render().

ReactDOM.render() is the most common way to render JSX. It takes a JSX expression, creates a corresponding tree of DOM nodes, and adds that tree to the DOM. That is the way to make a JSX expression appear on screen.

Move to the right a little more, and you come to this expression:

<h1>Hello world</h1>

 

This is the first argument being passed to ReactDOM.render(). ReactDOM.render()‘s first argument should be a JSX expression, and it will be rendered to the screen.

Move to the right a little more, and you will see this expression:

document.getElementById(‘app’)

 

You just learned that ReactDOM.render() makes its first argument appear on screen. But where on the screen should that first argument appear?

The first argument is appended to whatever element is selected by the second argument.

Create a html like and name it index.html with this content.

<!DOCTYPE html>
<html>
<body>
  <div id=“app”></div>
  <script src=“/app.js”></script>
</body>
</html>

 

 See if you can find an element that would be selected by document.getElementById(‘app’).

That element acted as a container for ReactDOM.render()‘s first argument! 

ReactDOM.render()‘s first argument should evaluate to a JSX expression, it doesn’t have to literally be a JSX expression.

The first argument could also be a variable, so long as that variable evaluates to a JSX expression.

In this example, we save a JSX expression as a variable named toDoList. We then pass toDoList as the first argument to ReactDOM.render():

const toDoList = (
  <ol>
    <li>Learn React</li>
    <li>Become a Developer</li>
  </ol>
);

ReactDOM.render(
  toDoList,
  document.getElementById(‘app’)
);

The Virtual DOM

One special thing about ReactDOM.render() is that it only updates DOM elements that have changed.

That means that if you render the exact same thing twice in a row, the second render will do nothing:

const hello = <h1>Hello world</h1>;

// This will add “Hello world” to the screen:

ReactDOM.render(hello, document.getElementById(‘app’));

// This won’t do anything at all:

ReactDOM.render(hello, document.getElementById(‘app’));

 

This is significant! Only updating the necessary DOM elements is a large part of what makes React so successful.

React accomplishes this thanks to something called the virtual DOM.

class vs className

To give a style to an element In HTML, it’s common to use class as an attribute name:

<h1 class=“big”>Hey</h1>

 

In JSX, you can’t use the word class! You have to use className instead:

<h1 className=“big”>Hey</h1>

 

This is because JSX gets translated into JavaScript, and class is a reserved word in JavaScript.

When JSX is rendered, JSX className attributes are automatically rendered as class attributes.

Self-Closing Tags

Most HTML elements use two tags: an opening tag (<div>), and a closing tag (</div>). However, some HTML elements such as <img> and <input> use only one tag. The tag that belongs to a single-tag element isn’t an opening tag nor a closing tag; it’s a self-closing tag.

When you write a self-closing tag in HTML, it is optional to include a forward-slash immediately before the final angle-bracket, but in JSX, you have to include the slash. If you write a self-closing tag in JSX and forget the slash, you will raise an error.

JavaScript Code In JSX

Any code in between the tags of a JSX element will be read as JSX, not as regular JavaScript! For example  <h1> 2 + 3 /h1> doesn’t add numbers – it reads them as text, just like HTML.

You need a way to write code that says, “Even though I am located in between JSX tags, treat me like ordinary JavaScript and not like JSX.”

You can do this by wrapping your code in curly braces. So  <h1> {2 + 3} /h1> renders 5.

 

You can now inject regular JavaScript into JSX expressions! This will be extremely useful. Here, you can see a JSX expression that displays the first twenty digits of pi.

const pi = (
  <div>
    <h1>
      PI Number
    </h1>
    <p>
      {Math.PI.toFixed(20)}
    </p>
  </div>
);

ReactDOM.render(
pi,
document.getElementById(‘app’)
);

 

Study the expression and notice the following:

  • The code is written in a JavaScript file. By default, it will all be treated as regular JavaScript.
  • Find <div> on line 5. From there up through </div>, the code will be treated as JSX.
  • Find Math. From there up through (20), the code will be treated as regular JavaScript again.
  • The curly braces themselves won’t be treated as JSX nor as JavaScript. They are markers that signal the beginning and end of a JavaScript injection into JSX, similar to the quotation marks that signal the boundaries of a string.

Variables in JSX

When you inject JavaScript into JSX, that JavaScript is part of the same environment as the rest of the JavaScript in your file.

That means that you can access variables while inside of a JSX expression, even if those variables were declared on the outside.

// Declare a variable:
const name = ‘Gerdo’;

// Access your variable
// from inside of a JSX expression:
const greeting = <p>Hello, {name}!</p>;

Variable Attributes in JSX

When writing JSX, it’s common to use variables to set attributes.

Here’s an example of how that might work:

// Use a variable to set the `height` and `width` attributes:

const sideLength = “200px”;

const panda = (
  <img
    src=“images/panda.jpg”
    alt=“panda”
    height={sideLength}
    width={sideLength} />
);

 

Notice how in this example, the <img />‘s attributes each get their own line. This can make your code more readable if you have a lot of attributes on one element.

Object properties are also often used to set attributes:

const pics = {
  panda: “http://bit.ly/1Tqltv5”,
  owl: “http://bit.ly/1XGtkM3”,
  owlCat: “http://bit.ly/1Upbczi”
};

const panda = (
  <img
    src={pics.panda}
    alt=”Lazy Panda” />
);

const owl = (
  <img
    src={pics.owl}
    alt=”Unimpressed Owl” />
);

const owlCat = (
  <img
    src={pics.owlCat}
    alt=”Ghastly Abomination” />
);

Event Listeners in JSX

JSX elements can have event listeners, just like HTML elements can. Programming in React means constantly working with event listeners.

You create an event listener by giving a JSX element a special attribute. Here’s an example:

<img onClick={myFunc} />

 

An event listener attribute’s name should be something like onClick or onMouseOver: the word on, plus the type of event that you’re listening for. You can see a list of valid event names here.

An event listener attribute’s value should be a function. The above example would only work if myFunc were a valid function that had been defined elsewhere:

function myFunc() {
  alert(‘Hello from myFunc’);
}

<img onClick={myFunc} />

 

Note that in HTML, event listener names are written in all lowercase, such as onclick or onmouseover. In JSX, event listener names are written in camelCase, such as onClick or onMouseOver.

JSX Conditionals: If Statements That Don’t Work

Great work! You’ve learned how to use curly braces to inject JavaScript into a JSX expression!

Here’s a rule that you need to know: you can not inject an if statement into a JSX expression.

This code will break:

(
  <h1>
    {
      if (purchase.complete) {
        ‘Thank you for placing an order!’
      }
    }
  </h1>
)

 

The reason why has to do with the way that JSX is compiled. You don’t need to understand the mechanics of it for now, but if you’re interested, then you can learn more here.

What if you want a JSX expression to render, but only under certain circumstances? You can’t inject an if statement. What can you do?

You have lots of options. In the next few lessons, we’ll explore some simple ways to write conditionals (expressions that are only executed under certain conditions) in JSX.

JSX Conditionals: If Statements That Do Work

How can you write a conditional, if you can’t inject an if statement into JSX?

Well, one option is to write an if statement, and not inject it into JSX.

Look at this code, Follow the if statement, all the way from line 6 down to line 18.

import React from ‘react’;
import ReactDOM from ‘react-dom’;

let message;

if (user.age >= drinkingAge) {
  message = (
    <h1>
      Hey, check out this alcoholic beverage!
    </h1>
  );
} else {
  message = (
    <h1>
      Hey, check out these earrings I got at Claire’s!
    </h1>
  );
}

ReactDOM.render(
  message,
  document.getElementById(‘app’)
);

 

It works, because the words if and else are not injected in between JSX tags. The if statement is on the outside, and no JavaScript injection is necessary.

This is a common way to express conditionals in JSX.

JSX Conditionals: The Ternary Operator

There’s a more compact way to write conditionals in JSX: the ternary operator.

The ternary operator works the same way in React as it does in regular JavaScript. However, it shows up in React surprisingly often.

Recall how it works: you write x ? y : z, where x, y, and z are all JavaScript expressions. When your code is executed, x is evaluated as either “truthy” or “falsy.” If x is truthy, then the entire ternary operator returns y. If x is falsy, then the entire ternary operator returns z. Here’s a nice explanation if you need a refresher.

Here’s how you might use the ternary operator in a JSX expression:

const headline = (
  <h1>
    { age >= drinkingAge ? ‘Buy Drink’ : ‘Do Teen Stuff’ }
  </h1>
);

 

In the above example, if age is greater than or equal to drinkingAge, then headline will equal <h1>Buy Drink</h1>. Otherwise, headline will equal <h1>Do Teen Stuff</h1>.

JSX Conditionals: &&

We’re going to cover one final way of writing conditionals in React: the && operator.

Like the ternary operator, && is not React-specific, but it shows up in React surprisingly often.

In the last two lessons, you wrote statements that would sometimes render a kitty and other times render a doggy. && would not have been the best choice for those lessons.

&& works best in conditionals that will sometimes do an action, but other times do nothing at all.

Here’s an example:

const tasty = (
  <ul>
    <li>Applesauce</li>
    { !baby && <li>Pizza</li> }
    { age > 15 && <li>Brussels Sprouts</li> }
    { age > 20 && <li>Oysters</li> }
    { age > 25 && <li>Grappa</li> }
  </ul>
);

 

Every time that you see && in this example, either some code will run, or else no code will run.

.map in JSX

The array method .map() comes up often in React. It’s good to get in the habit of using it alongside JSX.

If you want to create a list of JSX elements, then .map() is often your best bet. It can look odd at first:

const strings = [‘Home’, ‘Shop’, ‘About Me’];

const listItems = strings.map(string => <li>{string}</li>);

<ul>{listItems}</ul>

 

In the above example, we start out with an array of strings. We call .map() on this array of strings, and the .map() call returns a new array of <li>s.

On the last line of the example, note that {listItems} will evaluate to an array, because it’s the returned value of .map()! JSX <li>s don’t have to be in an array like this, but they can be.

// This is fine in JSX, not in an explicit array:

<ul>
  <li>item 1</li>
  <li>item 2</li>
  <li>item 3</li>
</ul>

// This is also fine!

const liArray = [
  <li>item 1</li>,
  <li>item 2<li>,
  <li>item 3</li>
];

<ul>{liArray}</ul>

Keys

When you make a list in JSX, sometimes your list will need to include something called keys:

<ul>
  <li key=“li-01”>Example1</li>
  <li key=“li-02”>Example2</li>
  <li key=”li-03″>Example3</li>
</ul>

A key is a JSX attribute. The attribute’s name is key. The attribute’s value should be something unique, similar to an id attribute.

keys don’t do anything that you can see! React uses them internally to keep track of lists. If you don’t use keys when you’re supposed to, React might accidentally scramble your list-items into the wrong order.

Not all lists need to have keys. A list needs keys if either of the following are true:

  1. The list-items have memory from one render to the next. For instance, when a to-do list renders, each item must “remember” whether it was checked off. The items shouldn’t get amnesia when they render.
  2. A list’s order might be shuffled. For instance, a list of search results might be shuffled from one render to the next.

If neither of these conditions are true, then you don’t have to worry about keys. If you aren’t sure then it never hurts to use them!

React.createElement

You can write React code without using JSX at all!

The majority of React programmers do use JSX, and we will use it for the remainder of this tutorial, but you should understand that it is possible to write React code without it.

The following JSX expression:

const h1 = <h1>Hello world</h1>;

 

can be rewritten without JSX, like this:

const h1 = React.createElement(
  “h1”,
  null,
  “Hello, world”
);

 

When a JSX element is compiled, the compiler transforms the JSX element into the method that you see above: React.createElement(). Every JSX element is secretly a call to React.createElement().

We won’t go in-depth into how React.createElement() works, but you can start with the documentation if you’d like to learn more!

Review

Congratulations! You have completed the unit on JSX. You’ve learned to create and render JSX elements! This is the first step towards becoming fluent in React.

You have learned a wide variety of JSX concepts. If you don’t feel like you’ve mastered them all yet, that’s okay! These concepts will come up again and again throughout this course, and the following courses.

You are now ready to put your JSX knowledge to use! It’s time to move on to the next major topic: React Components.