1. Introduction đ
Conditional rendering lets your components display different UI depending on the current state, props, or other data. Because JSX is powered by plain JavaScript, React doesn't need special syntax for conditionals â it reuses familiar JavaScript constructs like if, ternaries, and logical operators.
Information
2. What is Conditional Rendering? đ¤
Conditional rendering means choosing what to render based on a condition â showing a loading spinner while data fetches, displaying an error message, or rendering different content for logged-in versus logged-out users.
Code Snippet
function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return <h1>Welcome back! đ</h1>;
}
return <h1>Please sign in.</h1>;
}3. Why Conditional Rendering? đĄ
- Dynamic UI: Reflect the current application state accurately.
- Better UX: Show loading, error, or empty states appropriately.
- Access Control: Display content based on authentication or permissions.
- Feature Management: Toggle experimental features on or off.
4. Rendering with if đš
A plain if statement can be used before the return statement to decide what JSX gets returned.
Code Snippet
function StatusBadge({ isOnline }) {
if (isOnline) {
return <span className="badge green">Online</span>;
}
return <span className="badge gray">Offline</span>;
}Note
5. Rendering with if...else đ¸
Code Snippet
function UserPanel({ user }) {
if (user) {
return <p>Logged in as {user.name}</p>;
} else {
return <p>Not logged in</p>;
}
}Tip
6. Rendering with Ternary Operator â
The ternary operator (condition ? a : b) is an expression, making it ideal for inline conditionals directly within JSX.
Code Snippet
function StatusIcon({ isActive }) {
return (
<span>{isActive ? "đĸ Active" : "đ´ Inactive"}</span>
);
}Best Practice
7. Rendering with Logical && â
The logical AND operator renders its right-hand side only when the left-hand condition is true â useful for rendering something or nothing at all.
Code Snippet
function Notification({ hasUnread, count }) {
return (
<div>
{hasUnread && <span className="badge">{count} new</span>}
</div>
);
}Warning
8. Rendering with Logical || đ
The logical OR operator is useful for providing fallback content when a value is falsy, empty, or undefined.
Code Snippet
function UserName({ name }) {
return <p>{name || "Anonymous User"}</p>;
}Caution
9. Rendering with switch đ
For three or more mutually exclusive conditions, a switch statement (used before the return, or extracted into a helper function) is often clearer than chained ternaries.
Code Snippet
function StatusMessage({ status }) {
switch (status) {
case "loading":
return <p>Loading... âŗ</p>;
case "success":
return <p>Success! â
</p>;
case "error":
return <p>Something went wrong. â</p>;
default:
return <p>Idle</p>;
}
}10. Returning null đĢ
A component can return null to render nothing at all â useful for conditionally hiding a component entirely.
Code Snippet
function WarningBanner({ show, message }) {
if (!show) {
return null;
}
return <div className="warning">{message}</div>;
}Note
11. Conditional Variables đĻ
For complex conditions, assign the result to a variable before the return statement â this keeps the JSX itself clean and readable.
Code Snippet
function OrderStatus({ order }) {
let statusText;
if (order.isCancelled) {
statusText = "Cancelled â";
} else if (order.isDelivered) {
statusText = "Delivered đĻ";
} else {
statusText = "In Transit đ";
}
return <p>{statusText}</p>;
}12. Multiple Conditions đ§Š
Combine multiple boolean checks using logical operators (&&, ||) to express compound conditions.
Code Snippet
function SubmitButton({ isValid, isSubmitting }) {
const canSubmit = isValid && !isSubmitting;
return (
<button disabled={!canSubmit}>
{isSubmitting ? "Submitting..." : "Submit"}
</button>
);
}Tip
13. Nested Conditions đĒ
While nesting ternaries or conditionals is possible, deeply nested logic quickly becomes hard to read. Prefer extracting nested conditions into separate variables, helper functions, or components.
Avoid: Deeply Nested Ternaries
// â Hard to read
return isLoading ? <Spinner /> : error ? <ErrorMessage /> : data ? <Results data={data} /> : <EmptyState />;Prefer: Early Returns
// â
Much clearer
if (isLoading) return <Spinner />;
if (error) return <ErrorMessage />;
if (!data) return <EmptyState />;
return <Results data={data} />;14. Conditional Components đ§ą
Sometimes the cleanest approach is choosing which component to render entirely, rather than conditionally rendering fragments of JSX.
Code Snippet
function Dashboard({ role }) {
if (role === "admin") {
return <AdminDashboard />;
}
return <UserDashboard />;
}15. Conditional Props đī¸
Props themselves can be computed conditionally before being passed down, keeping the JSX tag itself clean.
Code Snippet
function SubmitButton({ isLoading }) {
const label = isLoading ? "Saving..." : "Save";
return <Button label={label} disabled={isLoading} />;
}16. Conditional Styling đ¨
Code Snippet
function AlertBox({ type }) {
const style = {
padding: "12px",
backgroundColor: type === "error" ? "#fee2e2" : "#dcfce7",
color: type === "error" ? "#991b1b" : "#166534",
};
return <div style={style}>Alert message</div>;
}17. Conditional Classes đˇī¸
Code Snippet
function Tab({ isActive, label }) {
return (
<button className={isActive ? "tab tab-active" : "tab"}>
{label}
</button>
);
}Tip
18. Conditional Attributes đ§
HTML attributes like disabled, checked, and required can be conditionally applied using boolean expressions directly.
Code Snippet
function SubmitButton({ isFormValid }) {
return <button disabled={!isFormValid}>Submit</button>;
}
function Checkbox({ isChecked }) {
return <input type="checkbox" checked={isChecked} readOnly />;
}19. Loading States âŗ
Code Snippet
function DataView({ isLoading, data }) {
if (isLoading) {
return <p>Loading data... âŗ</p>;
}
return <ul>{data.map((item) => <li key={item.id}>{item.name}</li>)}</ul>;
}Best Practice
20. Empty States đ
Code Snippet
function TodoList({ todos }) {
if (todos.length === 0) {
return <p>No todos yet. Add one to get started! â¨</p>;
}
return (
<ul>
{todos.map((todo) => <li key={todo.id}>{todo.text}</li>)}
</ul>
);
}Tip
21. Error States â ī¸
Code Snippet
function UserProfile({ user, error }) {
if (error) {
return <p className="error">Failed to load profile: {error.message}</p>;
}
return <h1>{user.name}</h1>;
}Warning
22. Authentication-Based Rendering đ
Code Snippet
function Navbar({ isAuthenticated }) {
return (
<nav>
{isAuthenticated ? (
<button onClick={logout}>Log Out</button>
) : (
<button onClick={login}>Log In</button>
)}
</nav>
);
}Note
23. Role-Based Rendering đĨ
Code Snippet
function AdminPanelLink({ role }) {
if (role !== "admin") {
return null;
}
return <a href="/admin">Admin Panel</a>;
}Tip
24. Feature Flag Rendering đŠ
Code Snippet
function App({ featureFlags }) {
return (
<div>
{featureFlags.newDashboard ? <NewDashboard /> : <LegacyDashboard />}
</div>
);
}Information
25. Permission-Based Rendering đĄī¸
Code Snippet
function DeleteButton({ permissions }) {
if (!permissions.includes("delete")) {
return null;
}
return <button className="danger">Delete</button>;
}Important
26. Best Practices đ
- Use early returns for readability instead of deeply nested ternaries.
- Extract complex conditions into named variables or helper functions.
- Always handle loading, empty, and error states explicitly.
- Use && carefully with numeric values to avoid rendering stray 0.
- Prefer ternaries for simple two-way branches, and switch or objects for many branches.
27. Common Mistakes đĢ
- Using {count && <Badge />} when count can be 0, accidentally rendering the number.
- Deeply nesting ternary operators, making the JSX difficult to read and debug.
- Forgetting to handle the loading state, causing errors when data is still undefined.
- Using if statements directly inside JSX curly braces, which is invalid syntax.
- Not returning null explicitly when a component should render nothing.
Danger
28. Performance Considerations âĄ
- Conditionally rendering components unmounts them when hidden â this resets their internal state, unlike CSS-based visibility toggling.
- For frequently toggled UI where state should persist (e.g., tab content), consider CSS display: none instead of removing the component from the tree.
- Avoid recalculating expensive conditional logic on every render â memoize with useMemo if needed.
Note
29. Frequently Asked Questions â
Question
Answer
Question
Answer
Question
Answer
30. Summary đ
Conditional rendering in React relies entirely on standard JavaScript constructs â if statements, ternaries, and logical operators â applied to JSX. Mastering these patterns, along with handling loading, empty, and error states gracefully, is essential for building polished, production-ready interfaces.
Summary
1. Introduction đ
Conditional rendering lets your components display different UI depending on the current state, props, or other data. Because JSX is powered by plain JavaScript, React doesn't need special syntax for conditionals â it reuses familiar JavaScript constructs like if, ternaries, and logical operators.
Information
2. What is Conditional Rendering? đ¤
Conditional rendering means choosing what to render based on a condition â showing a loading spinner while data fetches, displaying an error message, or rendering different content for logged-in versus logged-out users.
Code Snippet
function Greeting({ isLoggedIn }) {
if (isLoggedIn) {
return <h1>Welcome back! đ</h1>;
}
return <h1>Please sign in.</h1>;
}3. Why Conditional Rendering? đĄ
- Dynamic UI: Reflect the current application state accurately.
- Better UX: Show loading, error, or empty states appropriately.
- Access Control: Display content based on authentication or permissions.
- Feature Management: Toggle experimental features on or off.
4. Rendering with if đš
A plain if statement can be used before the return statement to decide what JSX gets returned.
Code Snippet
function StatusBadge({ isOnline }) {
if (isOnline) {
return <span className="badge green">Online</span>;
}
return <span className="badge gray">Offline</span>;
}Note
5. Rendering with if...else đ¸
Code Snippet
function UserPanel({ user }) {
if (user) {
return <p>Logged in as {user.name}</p>;
} else {
return <p>Not logged in</p>;
}
}Tip
6. Rendering with Ternary Operator â
The ternary operator (condition ? a : b) is an expression, making it ideal for inline conditionals directly within JSX.
Code Snippet
function StatusIcon({ isActive }) {
return (
<span>{isActive ? "đĸ Active" : "đ´ Inactive"}</span>
);
}Best Practice
7. Rendering with Logical && â
The logical AND operator renders its right-hand side only when the left-hand condition is true â useful for rendering something or nothing at all.
Code Snippet
function Notification({ hasUnread, count }) {
return (
<div>
{hasUnread && <span className="badge">{count} new</span>}
</div>
);
}Warning
8. Rendering with Logical || đ
The logical OR operator is useful for providing fallback content when a value is falsy, empty, or undefined.
Code Snippet
function UserName({ name }) {
return <p>{name || "Anonymous User"}</p>;
}Caution
9. Rendering with switch đ
For three or more mutually exclusive conditions, a switch statement (used before the return, or extracted into a helper function) is often clearer than chained ternaries.
Code Snippet
function StatusMessage({ status }) {
switch (status) {
case "loading":
return <p>Loading... âŗ</p>;
case "success":
return <p>Success! â
</p>;
case "error":
return <p>Something went wrong. â</p>;
default:
return <p>Idle</p>;
}
}10. Returning null đĢ
A component can return null to render nothing at all â useful for conditionally hiding a component entirely.
Code Snippet
function WarningBanner({ show, message }) {
if (!show) {
return null;
}
return <div className="warning">{message}</div>;
}Note
11. Conditional Variables đĻ
For complex conditions, assign the result to a variable before the return statement â this keeps the JSX itself clean and readable.
Code Snippet
function OrderStatus({ order }) {
let statusText;
if (order.isCancelled) {
statusText = "Cancelled â";
} else if (order.isDelivered) {
statusText = "Delivered đĻ";
} else {
statusText = "In Transit đ";
}
return <p>{statusText}</p>;
}12. Multiple Conditions đ§Š
Combine multiple boolean checks using logical operators (&&, ||) to express compound conditions.
Code Snippet
function SubmitButton({ isValid, isSubmitting }) {
const canSubmit = isValid && !isSubmitting;
return (
<button disabled={!canSubmit}>
{isSubmitting ? "Submitting..." : "Submit"}
</button>
);
}Tip
13. Nested Conditions đĒ
While nesting ternaries or conditionals is possible, deeply nested logic quickly becomes hard to read. Prefer extracting nested conditions into separate variables, helper functions, or components.
Avoid: Deeply Nested Ternaries
// â Hard to read
return isLoading ? <Spinner /> : error ? <ErrorMessage /> : data ? <Results data={data} /> : <EmptyState />;Prefer: Early Returns
// â
Much clearer
if (isLoading) return <Spinner />;
if (error) return <ErrorMessage />;
if (!data) return <EmptyState />;
return <Results data={data} />;14. Conditional Components đ§ą
Sometimes the cleanest approach is choosing which component to render entirely, rather than conditionally rendering fragments of JSX.
Code Snippet
function Dashboard({ role }) {
if (role === "admin") {
return <AdminDashboard />;
}
return <UserDashboard />;
}15. Conditional Props đī¸
Props themselves can be computed conditionally before being passed down, keeping the JSX tag itself clean.
Code Snippet
function SubmitButton({ isLoading }) {
const label = isLoading ? "Saving..." : "Save";
return <Button label={label} disabled={isLoading} />;
}16. Conditional Styling đ¨
Code Snippet
function AlertBox({ type }) {
const style = {
padding: "12px",
backgroundColor: type === "error" ? "#fee2e2" : "#dcfce7",
color: type === "error" ? "#991b1b" : "#166534",
};
return <div style={style}>Alert message</div>;
}17. Conditional Classes đˇī¸
Code Snippet
function Tab({ isActive, label }) {
return (
<button className={isActive ? "tab tab-active" : "tab"}>
{label}
</button>
);
}Tip
18. Conditional Attributes đ§
HTML attributes like disabled, checked, and required can be conditionally applied using boolean expressions directly.
Code Snippet
function SubmitButton({ isFormValid }) {
return <button disabled={!isFormValid}>Submit</button>;
}
function Checkbox({ isChecked }) {
return <input type="checkbox" checked={isChecked} readOnly />;
}19. Loading States âŗ
Code Snippet
function DataView({ isLoading, data }) {
if (isLoading) {
return <p>Loading data... âŗ</p>;
}
return <ul>{data.map((item) => <li key={item.id}>{item.name}</li>)}</ul>;
}Best Practice
20. Empty States đ
Code Snippet
function TodoList({ todos }) {
if (todos.length === 0) {
return <p>No todos yet. Add one to get started! â¨</p>;
}
return (
<ul>
{todos.map((todo) => <li key={todo.id}>{todo.text}</li>)}
</ul>
);
}Tip
21. Error States â ī¸
Code Snippet
function UserProfile({ user, error }) {
if (error) {
return <p className="error">Failed to load profile: {error.message}</p>;
}
return <h1>{user.name}</h1>;
}Warning
22. Authentication-Based Rendering đ
Code Snippet
function Navbar({ isAuthenticated }) {
return (
<nav>
{isAuthenticated ? (
<button onClick={logout}>Log Out</button>
) : (
<button onClick={login}>Log In</button>
)}
</nav>
);
}Note
23. Role-Based Rendering đĨ
Code Snippet
function AdminPanelLink({ role }) {
if (role !== "admin") {
return null;
}
return <a href="/admin">Admin Panel</a>;
}Tip
24. Feature Flag Rendering đŠ
Code Snippet
function App({ featureFlags }) {
return (
<div>
{featureFlags.newDashboard ? <NewDashboard /> : <LegacyDashboard />}
</div>
);
}Information
25. Permission-Based Rendering đĄī¸
Code Snippet
function DeleteButton({ permissions }) {
if (!permissions.includes("delete")) {
return null;
}
return <button className="danger">Delete</button>;
}Important
26. Best Practices đ
- Use early returns for readability instead of deeply nested ternaries.
- Extract complex conditions into named variables or helper functions.
- Always handle loading, empty, and error states explicitly.
- Use && carefully with numeric values to avoid rendering stray 0.
- Prefer ternaries for simple two-way branches, and switch or objects for many branches.
27. Common Mistakes đĢ
- Using {count && <Badge />} when count can be 0, accidentally rendering the number.
- Deeply nesting ternary operators, making the JSX difficult to read and debug.
- Forgetting to handle the loading state, causing errors when data is still undefined.
- Using if statements directly inside JSX curly braces, which is invalid syntax.
- Not returning null explicitly when a component should render nothing.
Danger
28. Performance Considerations âĄ
- Conditionally rendering components unmounts them when hidden â this resets their internal state, unlike CSS-based visibility toggling.
- For frequently toggled UI where state should persist (e.g., tab content), consider CSS display: none instead of removing the component from the tree.
- Avoid recalculating expensive conditional logic on every render â memoize with useMemo if needed.
Note
29. Frequently Asked Questions â
Question
Answer
Question
Answer
Question
Answer
30. Summary đ
Conditional rendering in React relies entirely on standard JavaScript constructs â if statements, ternaries, and logical operators â applied to JSX. Mastering these patterns, along with handling loading, empty, and error states gracefully, is essential for building polished, production-ready interfaces.