JSX Rules

JSX is a syntax similar to (X)HTML, but it is transpiled to JavaScript. This section highlights some of the features of JSX.

Composing Component

export default function Hello () {
  return <span>Hello</span>;
}
export default function World () {
  return <span>World</span>;
}
import Hello from "./Hello";
import World from "./World";

export default function HelloWorld () {
  return ( 
    <div> 
      <Hello/> <World/>! 
    </div> 
  );
}

Always wrap multi-line return in parentheses

The practice is exhibited above. The parentheses aren't strictly necessary, but if you leave them off, the opening tag must be on the same line:

import Hello from "./Hello";
import World from "./World";

export default function HelloWorld () {
  return <div> 
      <Hello/> <World/>! 
    </div>;
}

It is all too easy to make a mistake, so the safe practice is to always wrap multi-line return JSX in a pair of parentheses.

Return a single element

Notice how the two components are wrapped in a <div> in the HelloWorld example

Notice how <Hello/> and <World/> are wrapped in a <div> inside the HelloWorld component. A React component must return a single React element. Therefore, adjacent JSX elements must be wrapped in an enclosing tag.

You can always use a <div> to wrap JSX elements. Alternatively, you can use React fragments (since React 16.2):

import React from "react";
import Hello from "./Hello";
import World from "./World";

export default function HelloWorld () {
  return ( 
    <React.Fragment> 
      <Hello/> <World/>! 
    </React.Fragment> 
  );
}

The JSX equivalent for React fragment is the empty tag:

import Hello from "./Hello";
import World from "./World";

export default function HelloWorld () {
  return ( 
    <> 
      <Hello/> <World/>! 
    </> 
  );
}

Close every element

Notice how the <Hello/> and <World/> look like HTML elements with self-closing tags (such as <img /> or <input />). In HTML, you can eliminate the self-closing tag. In JSX, however, you must include it.

export default function Logo () {
  return <img src="logo.png" />;
}

Enclose JavaScript between {}

You can mix JavaScript with JSX. The JavaScript bits must be enclosed between {}.

export default function Greetings(){
  const name = "Ali";
  return <h1>Hello {name}</h1>;
} 

Moreover, the JavaScript inside the {} must be an expression (return a value).

If statement inside JSX

Since the JavaScript inside JSX must be an expression, you cannot use if-statements directly. Instead, you can use ternary expressions.

export default function Greetings({ isLoggedIn }){
  return (
    <div>
      The user is <b>{isLoggedIn ? "currently" : "not"}</b> logged in.
    </div>
  );
}

You can also use the boolean operators with truthy or falsy values to create conditional statements!

export default function Greetings({ isLoggedIn }){
  return (
    <div>
      {isLoggedIn && "The user is currently logged in."}
      {!isLoggedIn && "The user is not logged in."}
    </div>
  );
}

Looping over a list

Much like if statements, you cannot directly use loops inside JSX. Instead, you must use alternative approaches to, e.g., iterate over a list. For example, the array operations such as map, filter, and reduce are great choices.

const users = [
  {id: 1, name: "Mike"},
  {id: 2, name: "Peter"},
  {id: 3, name: "John"},
]

export default function UserList(){
  return (
    <ul>
      {
        users.map((user, index) => {
          return <li key={index}>Name: {user.name}</li>
        })
      }
    </ul>
  );
}

Lists and Keys

Notice the key attribute given to <li> element in the above code snippet. A "key" is a special string attribute you need to include when creating lists of elements. Keys help React identify which items have changed, are added, or are removed. The best way to pick a key is to use a string that uniquely identifies a list item among its siblings.

Use className instead of class

Use the special attribute className instead of class to assign "class" attribute to the element (so to avoid confusion with the class keyword in JavaScript).

export default function Header(){
  return (
    <div className="title">
      My cool application!
    </div>
  );
}

All HTML attribute names need to be camelCase

In JSX, all DOM properties and attributes (including event handlers) should be camelCased. So, for example, the HTML attribute tabindex corresponds to the attribute tabIndex in JSX. As another example, the event handler onclick must be provided as onClick in JSX.

const handleLogOut = () => alert("You are signed out!");

export default function Logout(){
  return (
    <button onClick={handleLogOut}>
      Sign out!
    </button>
  );
}