Runnable lesson · press Try it on the examples to edit and run them here.
Most of what you show on a screen comes from data. This lesson explains exactly what React does with each kind of value you put in braces.
What gets displayed
| Value | What React shows |
|---|---|
| String, number | The text |
| Array | Each item, one after another |
| JSX element | The element |
true, false, null, undefined | Nothing |
| Plain object | An error: objects are not valid as a React child |
function App() {
return (
<ul>
<li>Text: {"hello"}</li>
<li>Number: {42}</li>
<li>Array: {["a", "b", "c"]}</li>
<li>Boolean: {true}</li>
<li>Null: {null}</li>
<li>Undefined: {undefined}</li>
</ul>
);
}
The last three show nothing after their labels. That is a feature: it makes conditional rendering easy.
Show an object’s fields, not the object
function App() {
const person = { name: "Ada Lovelace", age: 36 };
// {person} would throw "Objects are not valid as a React child"
return <p>{person.name}, {person.age}</p>;
}
If you want to see an object while debugging, show it as text with JSON.stringify(person).
Formatting values
Format numbers, dates and currency before you show them. The built-in Intl and toLocaleString handle languages and regions properly:
function App() {
const price = 1299.5;
const created = new Date(Date.UTC(2026, 0, 15));
return (
<div>
<p>{new Intl.NumberFormat("en-US", { style: "currency", currency: "USD" }).format(price)}</p>
<p>{created.toLocaleDateString("en-US", { dateStyle: "long", timeZone: "UTC" })}</p>
</div>
);
}
See the JavaScript lessons on Intl.DateTimeFormat and numbers for more.
The 0 mistake
The expression {count && <Message />} shows the message only when count is truthy. But when count is 0, 0 && ... evaluates to 0, and React does render the number 0:
function App() {
const unread = 0;
return (
<div>
<p>Unread: {unread}</p>
<div>{unread && <b>You have mail</b>}</div>
</div>
);
}
Look at the preview: the second div shows a stray 0. Fix it by making the condition a real boolean:
function App() {
const unread = 0;
return (
<div>
<p>Unread: {unread}</p>
<div>{unread > 0 && <b>You have mail</b>}</div>
</div>
);
}
Escaping is automatic
If a string contains HTML, React shows it as text:
function App() {
const risky = "<b>not bold</b>";
return <p>{risky}</p>;
}
This protects your users. Do not work around it unless you fully control and sanitise the HTML.
Key points
- Strings, numbers and arrays are displayed; booleans,
nullandundefinedshow nothing. - Never render a plain object; render its fields.
- Beware
{number && ...}when the number can be0; compare with> 0.