Conditional Rendering
| Since: | React 16.8(2019) |
|---|
In React, conditional rendering refers to techniques for switching the displayed elements based on conditions. Because JavaScript's conditional syntax can be used directly inside JSX, you can intuitively build dynamic UIs.
Main Techniques
| Technique | Overview |
|---|---|
| if statement | The most basic conditional branching. Write a regular if statement before return to switch the JSX returned. |
| Ternary operator | Embeds a conditional expression inside JSX. Written in the form condition ? if true : if false. |
| && operator | Used when you want to display an element only when a condition is true. Written in the form condition && <element>. |
| Variable assignment | Store the conditional JSX in a variable and reference it inside return. Suitable for complex branching. |
| Returning null | Returning null from a component causes that component to render nothing. Used to toggle visibility. |
Syntax
// Conditional rendering using an if statement
function MyComponent(props) {
if (condition) {
return <ElementA />;
}
return <ElementB />;
}
// Embedding a ternary operator inside JSX
function MyComponent(props) {
return (
<div>
{condition ? <ElementA /> : <ElementB />}
</div>
);
}
// Displaying an element only when the condition is true using &&
function MyComponent(props) {
return (
<div>
{condition && <Element />}
</div>
);
}
Sample Code
An example of a component that switches content based on login state.
import { useState } from 'react';
// Message component for logged-in users
function WelcomeMessage({ name }) {
return <p>Welcome, {name}!</p>;
}
// Message component for guests
function GuestMessage() {
return <p>You are not logged in. Viewing as a guest.</p>;
}
// Notice banner component
// Returns null when show is false, rendering nothing
function NoticeBanner({ show, message }) {
if (!show) {
return null;
}
return <div className="banner">{message}</div>;
}
// App component (root component)
function App() {
// isLoggedIn manages login state
const [isLoggedIn, setIsLoggedIn] = useState(false);
const [hasNotice, setHasNotice] = useState(true);
return (
<div>
{/* && operator: shows the banner only when there is a notice */}
<NoticeBanner show={hasNotice} message="Maintenance notice available." />
{/* Ternary operator: switches component based on login state */}
{isLoggedIn
? <WelcomeMessage name="Tsunemori Akane" />
: <GuestMessage />
}
{/* Button to toggle login state */}
<button onClick={() => setIsLoggedIn(!isLoggedIn)}>
{isLoggedIn ? 'Log out' : 'Log in'}
</button>
{/* && operator: shows settings link only when logged in */}
{isLoggedIn && <a href="/settings?lang=en">Account Settings</a>}
</div>
);
}
export default App;
Notes
| Note | Overview |
|---|---|
| && operator and the number 0 | Writing 0 && <element> will render 0 on screen when the condition is falsy. Convert to boolean or use a ternary operator for safety: count > 0 && <element>. |
| null, undefined, and false are not rendered | When null, undefined, or false is returned inside JSX, React renders nothing. This can be used intentionally to avoid unintended output. |
| Use variable assignment for complex conditions | Deeply nested ternary operators make code hard to read. In such cases, assign JSX to a variable before return to keep things organized. |
Overview
Conditional rendering is a central technique for dynamically switching what is displayed based on a variety of conditions — user interactions, data state, authentication status, and more. In React, you can use JavaScript's own conditional syntax directly, so there is no special syntax to learn.
The && operator works well for simple show/hide toggling, and the ternary operator works well when switching between A and B. When branching becomes complex, using if statements or variable assignment to organize JSX helps keep code readable.
Returning null from a component renders nothing. This allows the display logic to be self-contained inside the component, without requiring the caller to handle conditions.
Common Mistakes
The && operator and the number 0
When you write count && <Comp />, if count is 0, the 0 itself is rendered on screen. The && operator returns the left-hand side when it is falsy — unlike false, the value 0 is rendered by React. Convert to Boolean or use a ternary operator to avoid this.
ng_example.jsx
// NG: when count is 0, "0" is displayed on screen
function NoticeList({ count }) {
return (
<div>
{count && <p>You have {count} notice(s).</p>}
</div>
);
}
Fixed:
ok_example.jsx
// OK: convert to Boolean so 0 is not rendered
function NoticeList({ count }) {
return (
<div>
{count > 0 && <p>You have {count} notice(s).</p>}
</div>
);
}
// OK: using a ternary operator
function NoticeListAlt({ count }) {
return (
<div>
{count ? <p>You have {count} notice(s).</p> : null}
</div>
);
}
The difference between null and undefined
Returning null causes React to render nothing, but returning undefined directly can cause an error. If a function component's return statement returns undefined, React will throw an error. Always return null explicitly when you want to render nothing.
ng_example.jsx
// NG: returning undefined causes an error
function StatusBadge({ status }) {
if (status === 'active') {
return <span>Tsunemori Akane: Inspector</span>;
}
// No return statement: the function returns undefined
}
Fixed:
ok_example.jsx
// OK: return null explicitly when rendering nothing
function StatusBadge({ status }) {
if (status === 'active') {
return <span>Tsunemori Akane: Inspector</span>;
}
return null;
}
Frequent mount/unmount of components due to conditional rendering
When a component disappears and reappears due to conditional rendering, its state is reset each time. Components with their own internal state — such as input forms — get reinitialized repeatedly, which can harm user experience. For UIs that toggle frequently, consider hiding visually with display: none or visibility: hidden instead.
ng_example.jsx
// NG: state is reset every time a tab is switched
function UserPanel({ user }) {
const [tab, setTab] = useState('profile');
return (
<div>
<button onClick={() => setTab('profile')}>Profile</button>
<button onClick={() => setTab('history')}>History</button>
{tab === 'profile' && <ProfileEditor user={user} />}
{tab === 'history' && <HistoryPanel user={user} />}
</div>
);
}
Fixed (hiding with CSS):
ok_example.jsx
// OK: hide with CSS instead of unmounting, so state is preserved
function UserPanel({ user }) {
const [tab, setTab] = useState('profile');
return (
<div>
<button onClick={() => setTab('profile')}>Profile</button>
<button onClick={() => setTab('history')}>History</button>
<div style={{ display: tab === 'profile' ? 'block' : 'none' }}>
<ProfileEditor user={user} />
</div>
<div style={{ display: tab === 'history' ? 'block' : 'none' }}>
<HistoryPanel user={user} />
</div>
</div>
);
}
If you find any errors or copyright issues, please contact us.