3.1 What is React?

What is JSX?

# Background

JSX is an extension to JavaScript that allows you to write UI (user interface) markup using a syntax that looks very much like HTML. This greatly simplifies the code that describes the UI. In some ways it is similar to template languages that you may have used like handlebars, but it comes with the full power of embedding JavaScript expressions.

Dynamic JavaScript expressions can be inserted anywhere inside JSX by wrapping them in curly braces {}. These opening and closing delimiters signal to the compiler that what is in between should be evaluated as a plain JavaScript expression and the resulting value inserted into the rest of the JSX markup.

# Example

// Written using React.createElement()
let message = 'Hello World';
let element = React.createElement('div', { className: 'container' }, message);

// Re-written using JSX
// Take note of the `{}` around the message variable
let message = 'Hello World';
let element = <div className="container">{message}</div>;
1
2
3
4
5
6
7
8

# JSX Syntax Tips & Trick

  1. If your JSX needs to span more than one line, wrap it in parentheses.
 





 

let element = (
  <div className="container">
    Lorem, ipsum dolor sit amet consectetur adipisicing elit. Recusandae quas
    quis quia incidunt illum aut culpa omnis. Dicta fugit sapiente dolor eveniet
    numquam, cum provident recusandae mollitia. Illo, qui a.
  </div>
);
1
2
3
4
5
6
7
  1. When specifying attributes values with JSX, use quotes for string literals, or curly braces to embed the result of a JavaScript expression, but not both for the same attribute.
let element = <img src={user.avatarUrl} alt="avatar" />;
1
  1. Like the vanilla JavaScript DOM APIs, attribute names in JSX follow the JavaScript convention of using camelCase rather than the HTML convention of using kabob-case, and a small number of attributes have a different name e.g. class becomes className and the for attribute on label elements become htmlFor.

  2. Elements with no corresponding closing tag like <img> or <input> MUST have a self-closing slash.

<img src="logo.png" alt="" /> <input type="text" />
1
  1. style attributes can be set with JavaScript objects, just like the standard DOM API. This can be either a variable holding the style object or an object literal. e.g.
// reference a variable
let myStyle = { color: 'green' };
let element1 = <p style={myStyle}>Some green text.</p>;

// insert an inline object literal
let element2 = <p style={{ color: 'purple' }}>Some purple text.</p>;
1
2
3
4
5
6
  1. Any given JSX block MUST have only one parent element. Any markup with adjacent sibling elements needs a single wrapping parent element. This can be a regular HTML Element, another React Element, or an Array.
// This is NOT ok
let element = (
  <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit.</p>
  <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit.</p>
)

// But this works
let element = (
  <div className='container'>
    <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit.</p>
    <p>Lorem, ipsum dolor sit amet consectetur adipisicing elit.</p>
  </div>
)

// And so does this
let elements = (
  <div>
  [
    <li key="1">Lorem, ipsum dolor sit amet consectetur adipisicing elit.</li>,
    <li key="2">Lorem, ipsum dolor sit amet consectetur adipisicing elit.</li>
  ]
  </div>
)

//and so will this
let element = (
  <>
   <p>First paragraph inside a Document Fragment.</p>
   <p>Second paragraph inside a Document Fragment.</p>
  </>
)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31

`key` attribute required with arrays of elements

When returning an array of JSX elements, each element in the array must have a unique identifier assigned to the key attribute.

If you don't have a parent element and don't want to add an extra div then you can use a Document Fragment created with <> and </>.

@see the React Docs for Lists and Keys (opens new window)

# Reference

Document Fragments (opens new window)

# Babel Compiler

Since the browser doesn't natively understand the JSX syntax extension, in order to generate the correct React Elements, we need to have a compiler to translate the JSX into regular JavaScript functions understandable to the browser, like React.createElement() method calls.

The defacto standard for this "transpilation" is Babel (opens new window) which is automatically bundled with most React projects. Of note, the Babel library is itself entirely written in JavaScript.

In addition to converting language extensions like JSX to plain JavaScript, Babel will convert modern ES2020 syntax to older JavaScript versions to ensure wider browser compatibility.

You can try it out with the live playground (opens new window) (REPL) environment on the Babel website. The example below is using the new conditional chaining (opens new window) syntax from ES2020.

// This ES2020 syntax

const person = {
  name: { first: 'Mickey', last: 'Mouse' },
};

if (person?.name?.first === 'Minni') {
  person.title = 'Handy Helper';
}
1
2
3
4
5
6
7
8
9
// Becomes this ES5 syntax

'use strict';

var _person$name;

var person = {
  name: {
    first: 'Mickey',
    last: 'Mouse',
  },
};

if (
  (person === null || person === void 0
    ? void 0
    : (_person$name = person.name) === null || _person$name === void 0
    ? void 0
    : _person$name.first) === 'Minni'
) {
  person.title = 'Handy Helper';
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

Learn more from the Babel Official Docs (opens new window) and from this Steve Griffith video tutorial, Getting Started with Babel (opens new window).

# Activity Requirements

# 1. Add Babel

Continuing with the simplified example that we have been using, add the Babel standalone in-browser transformer module from unpkg to your index.html file right after the React modules.

WARNING

This is fine for a quick demo or prototype, but please do not use this in production. Always pre-compile with a bundling tool like WebPack.



 

<script src="https://unpkg.com/react@17.0.2/umd/react.development.js"></script>
<script src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"></script>
<script src="https://unpkg.com/@babel/standalone@7.15.5/babel.js"></script>
1
2
3

You also need to tell the browser which script blocks should be interpreted by Babel. Set the type attribute on your custom JavaScript block to be text/babel.

<script type="text/babel">
  /* your code here ... */
</script>
1
2
3

# 2. Convert to JSX

Work in pairs for this activity. 10 minutes

Start with the following example code from the last exercise that uses the React.createElement() method and convert it to use JSX.

Don't forget to add Babel from the CDN.

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Hello React</title>
    <style>
      .container {
        font-size: 2rem;
        margin: 0 auto;
        width: 90vw;
      }
    </style>
  </head>
  <body>
    <div id="root"></div>

    <script
      src="https://unpkg.com/react@17.0.2/umd/react.development.js"
      crossorigin
    ></script>
    <script
      src="https://unpkg.com/react-dom@17.0.2/umd/react-dom.development.js"
      crossorigin
    ></script>
    <!-- add babel standalone script -->
    <!-- type  to script tag -->
    <script>
      const rootElement = document.getElementById('root');
      // The React Element can have many child elements
      const element = React.createElement(
        'div',
        { className: 'container' },
        React.createElement('h1', null, 'Hello React'),
        React.createElement(
          'main',
          null,
          React.createElement(
            'p',
            null,
            'I am ',
            React.createElement(
              'span',
              { style: { color: 'green' } },
              'one of'
            ),
            ' the grand-children'
          )
        )
      );

      ReactDOM.render(element, rootElement);
    </script>
  </body>
</html>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
Solution code
const rootElement = document.getElementById('root');
let highlightColor = 'green';
// Wrap the JSX in parentheses `()` if it needs to break over multiple lines.
const element = (
  <div className="container">
    <h1>Hello React</h1>
    <main>
      <p>
        I am <span style={{ color: highlightColor }}>one of</span> the
        grand-children
      </p>
    </main>
  </div>
);

ReactDOM.render(element, rootElement);
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16

# References

And next week we will be talking about Components with JSX

Last Updated: : 9/6/2021, 9:34:43 AM