JSX is how every component describes its output; its few rules differ from HTML in ways that trip up beginners.
JSX is a syntax extension that lets you write HTML-like markup inside JavaScript. The build tool compiles each tag to a function call (jsx("h1", {...})) that creates a plain object describing the element. So JSX is just JavaScript values: you can store it in variables, return it, and pass it around.
Curly braces switch back to JavaScript. Inside {} you can put any expression: a variable, user.name, formatDate(d), a ternary. Statements like if or for don't fit inside braces; compute values before the return instead.
How JSX differs from HTML:
- Every tag must be closed:
<img />,<br />. - Attributes are camelCase JavaScript property names:
className(notclass),htmlFor,onClick,tabIndex.aria-*anddata-*keep their dashes. styletakes an object:style={{ color: "red", fontSize: 14 }}. The outer braces mean "JavaScript", the inner ones are the object.- Text in braces is escaped automatically, so
{userInput}can't inject HTML. That's a security feature.
What renders: strings and numbers appear as text; null, undefined, true and false render nothing; arrays render each item. Objects are not valid children, so {user} throws; render {user.name}.
Comments inside JSX go in braces: {/* note */}.
Example
const user = {
name: "Hedy Lamarr",
imageUrl: "https://i.imgur.com/yXOvdOSs.jpg",
imageSize: 90,
};
export default function Profile() {
const alt = "Photo of " + user.name;
return (
<section className="profile">
<h1>{user.name}</h1>
{/* style takes an object; numbers mean px */}
<img
className="avatar"
src={user.imageUrl}
alt={alt}
style={{ width: user.imageSize, height: user.imageSize }}
/>
<label htmlFor="bio">Bio</label>
<textarea id="bio" defaultValue="Inventor" />
</section>
);
}Remember
{}embeds any JavaScript expression; compute statements beforereturn- Use
className,htmlForand camelCase event/attribute names; close every tag style={{ ... }}takes an object; text in braces is auto-escaped
Watch out for
- Rendering an object directly (
{user}) instead of one of its fields; React throws 'Objects are not valid as a React child'.