Embedding Expressions in JSX
Curly braces let JSX read values from JavaScript.
They are how React components mix UI structure with dynamic data.
function Welcome({ name }) {
return <h1>Hello, {name}</h1>;
}Expressions, Not Statements
Inside {}, JSX accepts JavaScript expressions.
An expression produces a value.
<p>{user.name}</p>
<p>{price * quantity}</p>
<p>{isOnline ? "Online" : "Offline"}</p>Statements control flow or perform actions. They do not produce a value in the way JSX needs.
// Invalid
<p>{if (isOnline) "Online"}</p>
// Invalid
<ul>{for (const item of items) <li>{item}</li>}</ul>Move statement logic before the return, or use expressions such as ternaries and .map().
function StatusLabel({ isOnline }) {
const label = isOnline ? "Online" : "Offline";
return <p>{label}</p>;
}Rendering Lists with map
Arrays are expressions, so .map() is the usual way to render repeated UI.
function TagList({ tags }) {
return (
<ul>
{tags.map((tag) => (
<li key={tag}>{tag}</li>
))}
</ul>
);
}The callback returns JSX for each item. React receives an array of elements.
Conditional Values
Use a ternary when you need either one UI branch or another.
function AuthButton({ isLoggedIn }) {
return (
<button>
{isLoggedIn ? "Sign out" : "Sign in"}
</button>
);
}Use && when you only want to show something if a condition is true.
function Inbox({ unreadCount }) {
return (
<header>
<h1>Inbox</h1>
{unreadCount > 0 && <strong>{unreadCount} unread</strong>}
</header>
);
}Watch out for numeric values with &&.
// If items.length is 0, React renders 0.
{items.length && <p>Items found</p>}
// Safer
{items.length > 0 && <p>Items found</p>}Values React Does and Does Not Render
React renders strings and numbers.
<p>{0}</p>
<p>{"Saved"}</p>React ignores true, false, null, and undefined.
<p>{false}</p>
<p>{null}</p>Objects are not valid as direct children.
// Invalid: objects are not directly renderable
<pre>{user}</pre>
// Valid for debugging
<pre>{JSON.stringify(user, null, 2)}</pre>Arrays can render if their items are renderable.
<p>{["React", " ", "JSX"]}</p>Calling Functions in JSX
You can call functions inside JSX, but keep render logic cheap and predictable.
function ProductPrice({ amount, currency }) {
return <p>{formatPrice(amount, currency)}</p>;
}Avoid doing expensive work directly in JSX on every render.
// Risky if sortProducts is expensive or mutates the array
{sortProducts(products).map((product) => (
<ProductRow key={product.id} product={product} />
))}Prefer preparing data above the return, especially when the logic needs names or comments.
Escaping and Text Safety
Values inserted with {} are escaped.
function SearchResult({ query }) {
return <p>Results for {query}</p>;
}If query contains HTML, React displays the characters as text. It does not execute scripts or parse tags.
This is safer than building HTML strings manually.
Common Mistakes
- Putting
iforforstatements directly inside{}. - Using
items.length && ...and accidentally rendering0. - Rendering an object directly instead of one of its fields.
- Calling a state setter while rendering, which can cause render loops.
- Doing heavy calculations in JSX instead of preparing values clearly.
Which value will React render as visible text?
Practice Challenge
Create a CartSummary component that receives items.
It should:
- show
Your cart is emptywhen there are no items - show the number of items when there are items
- render each item name in a list
- use stable keys from each item's
id
Starter data:
const items = [
{ id: "sku-1", name: "Keyboard" },
{ id: "sku-2", name: "Mouse" },
];Recap
Curly braces let JSX use JavaScript expressions. Use them for values, ternaries, function results, and arrays from .map(), but keep statements and expensive logic outside the markup.