JSX and Components
Write JSX, compose components and pass data down with props.
What you will learn
- Write valid JSX
- Pass and destructure props
- Use children
JSX is a syntax that lets you write HTML-like markup inside JavaScript. A build tool converts it to ordinary function calls. It is not a template language: it is JavaScript, so you have the full language available inside curly braces.
JSX rules
- A component returns one root element. Wrap siblings in a
<div>or a fragment<>...</>. - Close every tag, including
<img />and<br />. - Use
classNameinstead ofclass, andhtmlForinstead offor. - Attributes are camelCase:
onClick,tabIndex. - Put JavaScript expressions in
{ }. Style takes an object:style={{ color: "red" }}.
function Profile() {
const user = { name: "Ada", age: 36 };
const year = new Date().getFullYear();
return (
<>
<h2 className="title">{user.name}</h2>
<p>Born around {year - user.age}</p>
</>
);
}Props
Props are how a parent passes data to a child, exactly like function arguments. They arrive as one object, so destructure them in the parameter list. Props are read-only: a component must never change its own props.
function Greeting({ name, excited = false }) {
return <h1>Hello, {name}{excited ? "!" : "."}</h1>;
}
function App() {
return (
<>
<Greeting name="Ada" excited />
<Greeting name="Linus" />
</>
);
}Strings can be written in quotes; everything else (numbers, booleans, arrays, objects, functions) goes in braces: <Card count={3} tags={["a", "b"]} />.
Children and composition
Anything placed between a component's tags arrives as the special children prop, letting you build wrapper components.
function Card({ title, children }) {
return (
<section className="card">
<h3>{title}</h3>
{children}
</section>
);
}
<Card title="Tip">
<p>Small components are easier to reuse.</p>
</Card>;function Status({ online, unread }) {
if (!online) return <p>Offline</p>;
return (
<p>
Online {unread > 0 && <strong>({unread} new)</strong>}
</p>
);
}{count && <X />} renders the number 0 when count is 0. Write {count > 0 && ...} instead.
Try it yourself
Create a Button component that takes label and an optional variant prop ("primary" by default) and renders a button whose className includes the variant.
Show solution
function Button({ label, variant = "primary" }) {
return <button className={`btn btn-${variant}`}>{label}</button>;
}
<Button label="Save" />;
<Button label="Delete" variant="danger" />;