CodeOath
← All posts
React75 min total · 17 parts

React Fundamentals: Components, Hooks, and the Virtual DOM

Contents — Part 2 of 17: JSX and the Rendering Model
Part 2 of 17 · ~2 min

JSX and the Rendering Model

JSX — the HTML-like syntax inside a .jsx/.tsx file — isn't part of JavaScript. A build step (Babel, or the compiler built into your bundler) transforms it into plain function calls before it ever reaches the browser:

const element = <h1 className="title">Hello, {name}</h1>;

// compiles to (conceptually — modern tooling uses a slightly different
// runtime call, but the idea is identical):
const element = React.createElement("h1", { className: "title" }, "Hello, ", name);

React.createElement doesn't touch the DOM — it returns a plain JavaScript object (a React element) describing what should be on screen: a type ("h1", or a component function), props, and children. A React element is cheap to create and throw away; this is the object React diffs on every render.

A few JSX rules that trip people up because they look like HTML but aren't:

  • A component can only return one root node. Wrap siblings in a <div> or, to avoid an extra wrapper element in the DOM, a Fragment: <>...</> (shorthand for <React.Fragment>...</React.Fragment>).
  • class is className, for is htmlFor — because class and for are reserved words in JavaScript.
  • Every expression inside {} must be an expression, not a statement. {if (x) { ... }} is a syntax error; use a ternary, &&, or move the logic above the return instead.
  • Anything JavaScript-truthy/falsy renders accordingly{0 && <Banner />} actually renders the literal text 0, not nothing, because 0 is falsy but still a renderable value. This is a genuinely common bug: use {count > 0 && <Banner />} instead of {count && <Banner />} when count might be 0.

Conditional and list rendering

function Status({ isOnline }) {
  return <span>{isOnline ? "Online" : "Offline"}</span>;
}

function Notice({ show, children }) {
  return show && <div className="notice">{children}</div>;
}

function UserList({ users }) {
  return (
    <ul>
      {users.map((u) => (
        <li key={u.id}>{u.name}</li>
      ))}
    </ul>
  );
}

There's no special "if" or "for" syntax in JSX — conditionals are ternaries or &&, and lists are just .map() returning an array of elements. React can render arrays of elements directly, provided each one has a key (more on why in the reconciliation section below).