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:
<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.{} must be an expression, not a statement. {if (x) { ... }} is a syntax error; use a ternary, &&, or move the logic above the return instead.{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.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).