React Conditional Rendering
24 April 2025 | Category: React Js
Welcome to this beginner-friendly tutorial on React Conditional Rendering! Conditional rendering in React allows you to display different UI elements based on conditions, such as user input, state, or props, making your apps dynamic and interactive. In this guide, you’ll learn how to use ternary operators, logical operators, if statements, and other techniques to render content conditionally. We’ll apply these concepts by building a Task Dashboard App that shows tasks, filters them by status, and toggles a task form. By the end, you’ll be confident using conditional rendering to create flexible, user-friendly React applications.
What is Conditional Rendering?
Conditional rendering is the process of deciding what to render in a React component based on conditions. For example, you might show a “Welcome” message for logged-in users or a “Login” button for guests. React uses JavaScript logic (e.g., if, ternaries, or &&) within JSX to control what gets displayed.
Why Learn Conditional Rendering?
- Dynamic UI: Show or hide elements based on user actions or data (e.g., show completed tasks only).
- User Experience: Create intuitive interfaces that adapt to state (e.g., toggle a form).
- Flexibility: Build reusable components that render differently based on props or state.
- Core Skill: Conditional rendering is essential for most React applications, from dashboards to forms.
Prerequisites
Before starting, you should have:
- Basic knowledge of React (components, props, state, JSX, events) and JavaScript (ES6).
- Node.js and npm installed (download from nodejs.org).
- A code editor like Visual Studio Code.
- A terminal for running commands.
We’ll use Create React App to set up our project and Tailwind CSS for responsive, attractive styling, consistent with your preference for visually appealing designs.
Key Conditional Rendering Concepts
Let’s explore the main techniques for conditional rendering in React.
1. Ternary Operator
The ternary operator (condition ? valueIfTrue : valueIfFalse) is a concise way to render one of two elements based on a condition.
Example:
const Status = ({ isComplete }) => {
return <p>{isComplete ? 'Completed' : 'Pending'}</p>;
};
2. Logical AND Operator (&&)
The && operator renders an element only if the condition is true, useful for showing/hiding elements.
Example:
const Notification = ({ hasError }) => {
return <div>{hasError && <p className="text-red-500">Error occurred!</p>}</div>;
};
3. If Statements
Use if statements outside the return to choose what JSX to render, ideal for complex logic.
Example:
const Welcome = ({ isLoggedIn }) => {
if (isLoggedIn) {
return <p>Welcome back!</p>;
}
return <p>Please log in.</p>;
};
4. Null or Early Returns
Return null or nothing to render nothing under certain conditions.
Example:
const Loader = ({ isLoading }) => {
if (!isLoading) return null;
return <p>Loading...</p>;
};
5. Multiple Conditions
Combine conditions using if-else, ternaries, or switch statements for more complex rendering.
Example:
const Status = ({ status }) => {
if (status === 'success') return <p className="text-green-500">Success!</p>;
if (status === 'error') return <p className="text-red-500">Error!</p>;
return <p className="text-gray-500">Pending...</p>;
};
Setting Up the Project
Let’s create a React app to build our Task Dashboard App, which will use conditional rendering to filter tasks and toggle a form.
- Create a New React App:
Open your terminal and run:npx create-react-app task-dashboard cd task-dashboard - Install Tailwind CSS:
Install and configure Tailwind CSS for responsive styling:npm install -D tailwindcss npx tailwindcss initUpdatetailwind.config.js:/** @type {import('tailwindcss').Config} */ module.exports = { content: ['./src/**/*.{js,jsx,ts,tsx}'], theme: { extend: {} }, plugins: [] };Updatesrc/index.css:@tailwind base; @tailwind components; @tailwind utilities; body { font-family: Arial, sans-serif; margin: 0; background-color: #f5f5f5; } - Start the Development Server:
npm startThis opens your app athttp://localhost:3000. - Clean Up:
Opensrc/App.jsand replace its content with:const App = () => { return ( <div className="container mx-auto p-4"> <h1 className="text-3xl font-bold text-gray-800">Task Dashboard</h1> </div> ); }; export default App;Deletesrc/App.cssandsrc/logo.svg.
Building the Task Dashboard App
Our Task Dashboard App will:
- Display a list of tasks using a
Taskcomponent, with props for title, description, and completion status. - Allow users to toggle a form to add tasks using a
TaskFormcomponent. - Filter tasks by status (all, completed, pending) using buttons and conditional rendering.
- Use Tailwind CSS for a responsive, visually appealing design, aligning with your preference for attractive UI.
Step 1: Create the Task Component
- In
src, create a file namedTask.js:const Task = ({ title, description, isComplete }) => { return ( <div className="bg-white p-4 rounded-lg shadow-md mb-4 max-w-md"> <h3 className="text-lg font-semibold text-gray-800">{title}</h3> <p className="text-gray-600">{description}</p> <p className={`mt-2 ${isComplete ? 'text-green-500' : 'text-yellow-500'}`}> {isComplete ? 'Completed' : 'Pending'} </p> </div> ); }; Task.defaultProps = { title: 'Untitled Task', description: 'No description', isComplete: false }; export default Task;- Conditional Rendering:
- Uses a ternary operator to display “Completed” or “Pending” and apply green/yellow text.
- Renders props dynamically (
title,description,isComplete). - Styled with Tailwind CSS for a clean, responsive card layout.
- Conditional Rendering:
Step 2: Create the TaskForm Component
- In
src, create a file namedTaskForm.js:const TaskForm = ({ onAddTask }) => { const [title, setTitle] = React.useState(''); const [description, setDescription] = React.useState(''); const handleSubmit = (e) => { e.preventDefault(); if (title.trim() && description.trim()) { onAddTask({ title, description, isComplete: false }); setTitle(''); setDescription(''); } }; return ( <form onSubmit={handleSubmit} className="mb-6 max-w-md"> <div className="mb-4"> <input type="text" value={title} onChange={(e) => setTitle(e.target.value)} placeholder="Task title" className="w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" /> </div> <div className="mb-4"> <textarea value={description} onChange={(e) => setDescription(e.target.value)} placeholder="Task description" className="w-full p-2 border rounded-md focus:outline-none focus:ring-2 focus:ring-blue-500" /> </div> <button type="submit" className="bg-blue-500 text-white px-4 py-2 rounded-md hover:bg-blue-600" > Add Task </button> </form> ); }; export default TaskForm;- Conditional Rendering:
- No direct conditional rendering, but supports the app’s toggle feature by rendering only when shown.
- Uses events to handle form submission and pass data via
onAddTask. - Styled with Tailwind CSS for responsiveness.
- Conditional Rendering:
Step 3: Update the App Component
- Update
src/App.jsto manage tasks, filters, and conditional rendering:import Task from './Task'; import TaskForm from './TaskForm'; const App = () => { const [tasks, setTasks] = React.useState([ { title: 'Learn React', description: 'Study components and props', isComplete: true }, { title: 'Build App', description: 'Create a task dashboard', isComplete: false } ]); const [filter, setFilter] = React.useState('all'); const [showForm, setShowForm] = React.useState(false); const addTask = (newTask) => { setTasks([...tasks, newTask]); }; const filteredTasks = tasks.filter((task) => { if (filter === 'completed') return task.isComplete; if (filter === 'pending') return !task.isComplete; return true; // 'all' }); return ( <div className="container mx-auto p-4"> <h1 className="text-3xl font-bold text-gray-800 mb-6">Task Dashboard</h1> <div className="mb-4 flex space-x-2"> <button onClick={() => setFilter('all')} className={`px-4 py-2 rounded-md ${ filter === 'all' ? 'bg-blue-500 text-white' : 'bg-gray-200' }`} > All </button> <button onClick={() => setFilter('completed')} className={`px-4 py-2 rounded-md ${ filter === 'completed' ? 'bg-blue-500 text-white' : 'bg-gray-200' }`} > Completed </button> <button onClick={() => setFilter('pending')} className={`px-4 py-2 rounded-md ${ filter === 'pending' ? 'bg-blue-500 text-white' : 'bg-gray-200' }`} > Pending </button> </div> <button onClick={() => setShowForm(!showForm)} className="mb-6 bg-green-500 text-white px-4 py-2 rounded-md hover:bg-green-600" > {showForm ? 'Hide Form' : 'Add New Task'} </button> {showForm && <TaskForm onAddTask={addTask} />} <div className="grid grid-cols-1 sm:grid-cols-2 gap-4"> {filteredTasks.length > 0 ? ( filteredTasks.map((task, index) => ( <Task key={index} title={task.title} description={task.description} isComplete={task.isComplete} /> )) ) : ( <p className="text-gray-500">No tasks match the selected filter.</p> )} </div> </div> ); }; export default App;- Conditional Rendering:
- Uses
&&to showTaskFormonly whenshowFormis true (showForm && <TaskForm />). - Uses a ternary operator to render tasks or a “No tasks” message (
filteredTasks.length > 0 ? ... : ...). - Filters tasks conditionally based on
filterstate (all,completed,pending). - Dynamically styles filter buttons using ternaries for active/inactive states.
- Uses
- Other Features:
- Manages state with
useStatefor tasks, filter, and form visibility. - Passes
onAddTaskas a prop toTaskFormfor adding tasks. - Uses Tailwind CSS for a responsive grid layout and button styling.
- Manages state with
- Conditional Rendering:
Step 4: Test the App
- Save all files and ensure the development server is running (
npm start). - Open
http://localhost:3000. You should see:- Two initial tasks (“Learn React” and “Build App”) in a responsive grid.
- Filter buttons to show all, completed, or pending tasks.
- A toggle button to show/hide the task form.
- A form to add new tasks when visible.
- Try:
- Clicking filter buttons to show only completed or pending tasks.
- Toggling the form and adding a task (e.g., “Test App,” “Run tests”).
- Checking responsiveness by resizing the browser or using mobile view in dev tools.
Understanding the Code
Let’s recap how conditional rendering powers our Task Dashboard App:
- Ternary Operator: Used in
Appto render tasks or a “No tasks” message (filteredTasks.length > 0 ? ... : ...) and inTaskfor status text/color. - Logical AND (
&&): ShowsTaskFormonly whenshowFormis true (showForm && <TaskForm />). - Filter Logic: Uses
filterstate and.filter()to conditionally render tasks based on status. - Dynamic Styling: Applies conditional Tailwind classes to filter buttons based on
filterstate. - Responsive Design: Tailwind CSS ensures a mobile-friendly grid layout, aligning with your preference for attractive, responsive UI.
- ES6 Features:
- Arrow functions for components and handlers.
- Destructuring props (
{ title, description, isComplete }). - Spread operator to update state (
[...tasks, newTask]). - Modules for component organization.
Best Practices for Conditional Rendering
- Keep JSX Clean: Move complex logic to variables or functions outside the
return:const message = isLoggedIn ? 'Welcome!' : 'Please log in'; return <p>{message}</p>; - Use Early Returns: Return
nullor simple JSX for simple conditions to avoid nested logic:if (!data) return <p>Loading...</p>; - Avoid Overusing Ternaries: Use
ifstatements for complex conditions to improve readability:if (status === 'success') { return <p>Success!</p>; } - Ensure Unique Keys: Use unique
keyprops when rendering lists (key={index}is okay for static lists, but IDs are better). - Test Edge Cases: Handle empty states or invalid data with fallback UI (e.g., “No tasks” message).
- Optimize Performance: Memoize components with
React.memoif conditional rendering causes frequent re-renders.
Common Conditional Rendering Pitfalls and Fixes
- Nested Ternaries:
Problem: Multiple ternaries (e.g.,a ? b : c ? d : e) are hard to read.
Fix: Useifstatements or extract logic to a function:const getStatus = (status) => { if (status === 'success') return 'Success'; if (status === 'error') return 'Error'; return 'Pending'; }; - Rendering
undefinedornull:
Problem: Forgetting to handle falsy conditions causes blank UI.
Fix: Use&&or ternaries to provide fallbacks:{data && <p>{data}</p>} - Missing Keys in Lists:
Problem: Lists withoutkeyprops cause warnings or rendering issues.
Fix: Add uniquekeyprops:tasks.map((task, index) => <Task key={task.id} />) - Overcomplicating JSX:
Problem: Complex logic in JSX reduces readability.
Fix: Move logic outside thereturn:const content = condition ? <ComponentA /> : <ComponentB />; return <div>{content}</div>;
Conditional Rendering in Functional vs. Class Components
Since you’ve explored class components previously, here’s how conditional rendering differs:
- Functional Components: Use JavaScript logic directly in the function body or JSX:
const Task = ({ isComplete }) => { return <p>{isComplete ? 'Done' : 'Todo'}</p>; }; - Class Components: Use
this.propsorthis.statein therendermethod:class Task extends React.Component { render() { return <p>{this.props.isComplete ? 'Done' : 'Todo'}</p>; } }
Our app uses functional components for simplicity and alignment with modern React, but the conditional rendering techniques apply to both.
What’s Next?
You’ve built a Task Dashboard App using React conditional rendering! Here are some next steps:
- Add Features: Implement a button to toggle task completion status, updating
isCompletein state. - Learn More Techniques: Explore
useEffectfor conditional side effects or Context for shared state. - Enhance Styling: Add animations with Tailwind CSS or Framer Motion for smoother transitions.
- Build Another App: Create a weather app or product filter to practice conditional rendering.
Practice Challenge
Add a “Clear Completed” button that removes all completed tasks from the list. Use conditional rendering to show the button only when there are completed tasks.
Resources
- React Documentation: Conditional Rendering
- React Documentation: Rendering Lists
- Tailwind CSS Documentation
- MDN: ES6
- Create React App Guide
Congratulations on mastering React conditional rendering! You’re now equipped to build dynamic, adaptive UIs. Keep practicing and happy coding!