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 init
Updatetailwind.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 start
This opens your app athttp://localhost:3000
. - Clean Up:
Opensrc/App.js
and 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.css
andsrc/logo.svg
.
Building the Task Dashboard App
Our Task Dashboard App will:
- Display a list of tasks using a
Task
component, with props for title, description, and completion status. - Allow users to toggle a form to add tasks using a
TaskForm
component. - 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.js
to 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 showTaskForm
only whenshowForm
is true (showForm && <TaskForm />
). - Uses a ternary operator to render tasks or a “No tasks” message (
filteredTasks.length > 0 ? ... : ...
). - Filters tasks conditionally based on
filter
state (all
,completed
,pending
). - Dynamically styles filter buttons using ternaries for active/inactive states.
- Uses
- Other Features:
- Manages state with
useState
for tasks, filter, and form visibility. - Passes
onAddTask
as a prop toTaskForm
for 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
App
to render tasks or a “No tasks” message (filteredTasks.length > 0 ? ... : ...
) and inTask
for status text/color. - Logical AND (
&&
): ShowsTaskForm
only whenshowForm
is true (showForm && <TaskForm />
). - Filter Logic: Uses
filter
state and.filter()
to conditionally render tasks based on status. - Dynamic Styling: Applies conditional Tailwind classes to filter buttons based on
filter
state. - 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
null
or simple JSX for simple conditions to avoid nested logic:if (!data) return <p>Loading...</p>;
- Avoid Overusing Ternaries: Use
if
statements for complex conditions to improve readability:if (status === 'success') { return <p>Success!</p>; }
- Ensure Unique Keys: Use unique
key
props 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.memo
if 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: Useif
statements or extract logic to a function:const getStatus = (status) => { if (status === 'success') return 'Success'; if (status === 'error') return 'Error'; return 'Pending'; };
- Rendering
undefined
ornull
:
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 withoutkey
props cause warnings or rendering issues.
Fix: Add uniquekey
props: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.props
orthis.state
in therender
method: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
isComplete
in state. - Learn More Techniques: Explore
useEffect
for 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!