- Home
- /
- Tutorials
- /
- React Tutorial
- /
- Expressions in JSX
JSX
Expressions in JSX
Curly braces switch from markup back to JavaScript. Anything that produces a value is allowed; anything that does not is a syntax error.
Expressions, not statements
An expression produces a value: 2 + 2, user.name, items.map(...), a ternary. A statement does something: if, for, const. Only expressions go inside braces.
What fits in braces
jsx
function Demo() {
const user = { name: "Ada", visits: 3 }
const items = ["one", "two"]
return (
<div>
<p>Maths: {2 + 2}</p>
<p>Property: {user.name}</p>
<p>Call: {user.name.toUpperCase()}</p>
<p>Ternary: {user.visits > 1 ? "Returning" : "First time"}</p>
<p>Template: {`${user.name} has ${user.visits} visits`}</p>
<ul>{items.map((item) => <li key={item}>{item}</li>)}</ul>
</div>
)
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<Demo />)An if statement inside braces will not compile. Use a ternary inline, or compute the value above the return where statements are allowed.
What React actually renders
Strings and numbers render as text. Arrays render each item in turn. But several values render as nothing at all, silently, and that catches people out.
Values that disappear
jsx
function Falsy() {
return (
<div>
<p>Zero renders: [{0}]</p>
<p>Empty string renders nothing: [{""}]</p>
<p>null renders nothing: [{null}]</p>
<p>undefined renders nothing: [{undefined}]</p>
<p>false renders nothing: [{false}]</p>
<p>But an array renders each item: [{[1, 2, 3]}]</p>
</div>
)
}
const root = ReactDOM.createRoot(document.getElementById("root"))
root.render(<Falsy />)Note the odd one out: zero renders. That is the source of a very common bug, where {items.length && <List />} puts a bare 0 on the page when the list is empty. The conditional rendering chapter deals with it properly.
Keep the logic above the return
Braces accept one expression, so a long ternary chain inside JSX quickly becomes unreadable. Anything past a simple condition belongs above the return, where you have the whole language available.
This is not only about tidiness. A variable computed above the return can be named, which turns {user.visits > 1 ? "Returning" : "First time"} into {greeting} - and the next person reads the name rather than re-deriving the condition.
Comments and whitespace
A comment inside JSX is an expression too: {/* like this */}. And JSX collapses whitespace between lines, so {" "} is how you force a space that would otherwise vanish.
- Braces take one expression, not a block of statements.
- Compute anything complicated above the
return. 0renders;null,undefined,falseand""do not.- Objects cannot be rendered - React throws rather than guessing.
