Conditional rendering
Conditional rendering means showing different markup depending on data: whether a task is done, whether a list is empty. JSX has no special constructs for this — you use the plain if, the ternary operator and && from JavaScript.
A condition with if
A component can return different markup. Let TodoList show a message when there are no tasks:
// src/components/TodoList.jsx
import TodoItem from './TodoItem.jsx';
export default function TodoList({ todos }) {
if (todos.length === 0) {
return <p>No tasks. Time to rest.</p>;
}
return (
<ul>
{todos.map((todo) => (
<TodoItem key={todo.id} todo={todo} />
))}
</ul>
);
}Pass an empty array from App — <TodoList todos={[]} /> — and the page shows "No tasks. Time to rest.".
The ternary operator
When only part of the markup differs, write the condition right in JSX with ? :. Let us mark finished tasks in src/components/TodoItem.jsx:
// src/components/TodoItem.jsx
export default function TodoItem({ todo }) {
return (
<li>
{todo.done ? '✓' : '○'} {todo.text}
</li>
);
}A finished task gets a check mark, the rest get a circle.
The && operator
When you need to show something or nothing, use &&. The right side is rendered only when the left side is truthy:
// src/components/TodoItem.jsx
export default function TodoItem({ todo }) {
return (
<li>
{todo.text}
{todo.done && <span> (done)</span>}
</li>
);
}Finished tasks get "(done)" after the text, the others get nothing.
A condition in an attribute
Conditions work in attributes too. For example, a class for striking through:
// src/components/TodoItem.jsx
export default function TodoItem({ todo }) {
return <li className={todo.done ? 'done' : ''}>{todo.text}</li>;
}With the rule .done { text-decoration: line-through; } in src/index.css, finished tasks are struck through.
What React does not render
| Value in curly braces | What appears on the page |
|---|---|
null, undefined | Nothing |
true, false | Nothing |
0 | The digit 0 |
'' (empty string) | Nothing |
Returning null from a component is a way to show nothing.
Complex conditions
With more than two options, do not nest ternary operators — they are hard to read. Work out the result in advance with if in the component body and render the variable.
Common mistake
The number 0 is falsy, but React renders it. So with an empty list the page shows "0":
// Wrong: {todos.length && <TodoList todos={todos} />}
function Tasks({ todos }) {
return <div>{todos.length > 0 && <TodoList todos={todos} />}</div>;
}The left side of && must be a boolean: the comparison > 0 instead of a bare number.