JSX & Elements
JSX is just syntax
Section titled “JSX is just syntax”JSX looks like HTML, but it is syntax sugar for regular JavaScript function calls. This:
const el = <button className="primary">Click</button>;compiles (via the modern JSX transform) to roughly:
import { jsx as _jsx } from "react/jsx-runtime";const el = _jsx("button", { className: "primary", children: "Click" });The important consequence: JSX is an expression. It evaluates to a value you can store in a variable, return from a function, put in an array, or pass as a prop. It isn’t a template language with its own rules — it’s JavaScript, so { } inside JSX just drops back into a JS expression.
function List({ items, showHeader }) { return ( <ul> {showHeader && <li className="header">Items</li>} {/* JS expression */} {items.map((item) => ( <li key={item.id}>{item.text}</li> {/* JS expression */} ))} </ul> );}An element is a plain object
Section titled “An element is a plain object”What does _jsx("button", ...) actually return? Not a DOM node — a plain JavaScript object describing what you want:
// Roughly what a React element is:const el = { type: "button", // a string for host elements, or a function for components props: { className: "primary", children: "Click" }, key: null, // ...internal fields};This is the key insight: a React element is a cheap, immutable description — not the real thing. Creating a thousand elements is just creating a thousand small objects. React builds a tree of these descriptions on every render, then compares it to the previous tree to decide what actual DOM to touch (that’s reconciliation, next lesson).
flowchart LR
jsx["JSX
<button>Click</button>"] -->|compiler| call["jsx('button', props)"]
call --> obj["element object
{ type, props, key }"]
obj --> tree["tree of elements
(the description)"]
tree -->|React| dom["real DOM
(the result)"] Components vs host elements
Section titled “Components vs host elements”The type field tells React what kind of node it is:
- A string type (
"button","div") is a host element — React knows how to turn it into a real DOM node. - A function type (
Counter,Greeting) is a component — React calls that function to get more elements, recursively, until it bottoms out in host elements.
<Counter />// element: { type: Counter (the function), props: {} }// React calls Counter() → gets more elements → repeats until only host elements remainThis is why a component name must be capitalized in JSX: <Counter /> (capital) means “call the Counter component,” while <counter /> (lowercase) means “create a host element literally named counter.” The capitalization is how the compiler decides between a string type and a variable reference.