Conditional rendering is a powerful feature in React that allows developers to render components based on certain conditions.
It is a fundamental concept that plays a crucial role in building dynamic and interactive web applications.
In this comprehensive guide, we will dive deep into conditional rendering in React, covering basic and advanced techniques with examples for proper understanding.
Understanding Conditional Rendering in React
Conditional rendering in React allows developers to dynamically control what content is displayed on the screen based on specific values which can be stored in a variable, state, or props.
This can be extremely useful in scenarios where you want to show or hide certain UI elements, change the layout of a page, or render different content based on user interactions.
Conditional rendering is important in React applications because it enables you to create dynamic and interactive user interfaces that can respond to changing data and user interactions in real time.
It will help improve the performance and efficiency of your applications by avoiding unnecessary rendering of components or elements that are not needed.
Basic Techniques for Conditional Rendering
There are several basic techniques that you can use for conditional rendering in React. Let’s explore each of them in detail.
Using the if Statement for Conditional Rendering
One of the most straightforward ways to implement conditional rendering in React is by using the traditional if
statement.
if (condition) {
return <p>Expression 1</p>;
} else {
return <p>Expression 2</p>;
}
The JavaScript’s if
statement can be used inside your component’s render()
method to conditionally render content based on a certain condition.
For example, you can use the if statement to display a loading spinner while waiting for data to load:
import { useState, useEffect } from 'react';
import Spinner from './Spinner';
const MyComponent = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
// Fetch data from an API
fetch('https://example.com/data')
.then((response) => response.json())
.then((data) => {
setData(data);
setIsLoading(false);
});
}, []);
if (isLoading) {
return <Spinner />;
}
return <div>{/* Render the data here */}</div>;
};
export default MyComponent;
In this example, MyComponent
fetches data from an API using the useEffect
hook. While waiting for the data to load, we display a Spinner component using the if
statement.
Another example can be rendering a fallback UI when an error occurs while rendering your component:
const MyComponent = ({ data }) => {
if (!data) {
return <p>Something went wrong. Please try again later.</p>;
}
return <div>{/* Render the data here */}</div>;
};
export default MyComponent;
In this code, we have a MyComponent
that takes a data
prop. If the data
prop is falsy, we render an error message using the if
statement.
Finally, you can display different content for different user roles with the if
statement:
const MyComponent = ({ user }) => {
if (user.role === 'admin') {
return <p>Welcome, admin!</p>;
} else if (user.role === 'user') {
return <p>Welcome, user!</p>;
} else {
return <p>You are not authorized to access this page.</p>;
}
};
export default MyComponent;
In this code, we have a MyComponent
that takes a user
prop. Depending on the user.role
property, we display different content using the if
statement.
Using the Ternary Operator for Conditional Rendering
Another concise way to implement conditional rendering in React is by using the ternary operator (?) inside JSX.
The ternary operator allows you to write a compact inline if-else statement by specifying 3 operands. The first operand is the condition, while the other two operands are the expressions. If the condition is true
, the first expression will be executed; otherwise, the second expression.
For example, you can render different components based on a prop:
import ComponentA from './ComponentA';
import ComponentB from './ComponentB';
const ExampleComponent = ({ shouldRenderComponentA }) => {
return (
<div>
{shouldRenderComponentA ? <ComponentA /> : <ComponentB />}
</div>
);
};
export default ExampleComponent;
In this code, we have an ExampleComponent
that takes a prop called shouldRenderComponentA
. We use the ternary operator to conditionally render either ComponentA
or ComponentB
based on the prop value.
You can also render different text based on a state:
import { useState } from 'react';
const ExampleComponent = () => {
const [showMessage, setShowMessage] = useState(false);
return (
<div>
<button onClick={() => setShowMessage(!showMessage)}>
{showMessage ? 'Hide message' : 'Show message'}
</button>
{showMessage ? <p>Hello, world!</p> : null}
</div>
);
};
export default ExampleComponent;
In this example, we use the ternary operator to conditionally render different text depending on the value of the showMessage
state. When the button is clicked, the value of showMessage
is toggled, and the text is displayed or hidden accordingly.
Finally, you can render a loading spinner while data is being fetched:
import { useState, useEffect } from 'react';
import Spinner from './Spinner';
const ExampleComponent = () => {
const [isLoading, setIsLoading] = useState(true);
const [data, setData] = useState(null);
useEffect(() => {
const fetchData = async () => {
const response = await fetch('https://jsonplaceholder.typicode.com/todos/1');
const jsonData = await response.json();
setData(jsonData);
setIsLoading(false);
};
fetchData();
}, []);
return (
<div>
{isLoading ? <Spinner /> : <p>{data.title}</p>}
</div>
);
};
export default ExampleComponent;
In this example, we use the ternary operator to conditionally render a loading spinner while data is being fetched from an API. Once the data is available, we render the title
property using the ternary operator.
Using Logical AND and OR Operators for Conditional Rendering
You can also use the logical AND (&&
) and OR (||
) operators to implement conditional rendering in React.
The logical AND operator allows you to render a component only if a certain condition is true, while the logical OR operator allows you to render a component if either of the conditions is true.
These operators are useful when you have simple conditions that determine whether a component should be rendered or not. For example, if you want to render a button only if a form is valid, you can use the logical AND operator like this:
import { useState } from 'react';
const FormComponent = () => {
const [formValues, setFormValues] = useState({ username: "", password: "" });
const isFormValid = formValues.username && formValues.password;
const handleSubmit = (event) => {
event.preventDefault();
// Submit form data
};
return (
<form onSubmit={handleSubmit}>
<input
type="text"
value={formValues.username}
placeholder="Type Username..."
onChange={(e) =>
setFormValues({ ...formValues, username: e.target.value })
}
/>
<br />
<input
type="password"
value={formValues.password}
placeholder="Type Password..."
onChange={(e) =>
setFormValues({ ...formValues, password: e.target.value })
}
/>
{isFormValid && <button type="submit">Submit</button>}
</form>
);
};
export default FormComponent;
In this example, we have a FormComponent
that has a form with two input fields for username
and password
. We’re using useState
hook to manage the form values and isFormValid
variable to check if both input fields have values. Using the logical AND operator (&&), we render the submit button only if isFormValid
is true. This ensures that the button is only enabled when the form is valid.
Similarly, you can use the OR operator to render a loading message if data is still loading or an error message if an error occurs:
import React, { useEffect, useState } from 'react';
const DataComponent = () => {
const [data, setData] = useState(null);
const [isLoading, setIsLoading] = useState(true);
const [errorMessage, setErrorMessage] = useState('');
useEffect(() => {
const fetchData = async () => {
try {
const response = await fetch('https://api.example.com/data');
const data = await response.json();
setData(data);
} catch (error) {
setErrorMessage('An error occurred while fetching data.');
} finally {
setIsLoading(false);
}
};
fetchData();
}, []);
return (
<>
{errorMessage || isLoading ? (
<p>{errorMessage || 'Loading...'}</p>
) : (
<ul>
{data.map((item) => (
<li key={item.id}>{item.name}</li>
))}
</ul>
)}
</>
);
};
export default DataComponent;
In this example, a DataComponent
fetches data from an API using fetch and displays it in a list. We’re using useState
hook to manage the data, loading state, and error message. Using the logical OR operator (||), we can render a loading message or an error message if either of its conditions is true. This ensures that the user sees a message indicating the current state of the data fetching process.
Using the logical AND and OR operators for conditional rendering in React is a concise and readable way to handle simple conditions. However, it’s better to use other approaches like switch
statements for more complex logic.
Advanced Techniques for Conditional Rendering
Conditional rendering in React can be more complex depending on the requirements of your application. Here are some advanced techniques that you can use for conditional rendering in more complex scenarios.
Using Switch Statements for Conditional Rendering
While if statements and ternary operators are common approaches for conditional rendering, sometimes a switch
statement can be more appropriate, especially when dealing with multiple conditions.
Here’s an example:
import React from 'react';
const MyComponent = ({ userType }) => {
switch (userType) {
case 'admin':
return <p>Welcome, admin user!</p>;
case 'user':
return <p>Welcome, regular user!</p>;
default:
return <p>Please log in to continue.</p>;
}
};
export default MyComponent;
In this code, a switch
statement is used to render content based on the userType
prop conditionally. This approach can be helpful when dealing with multiple conditions and provides a more organized and readable way to handle complex logic.
Conditional Rendering With React Router
React Router is a popular library for handling client-side routing in React applications. React Router allows you to render components based on the current route conditionally.
Here’s an example of implementing conditional rendering using React Router:
import { useState } from 'react';
import { BrowserRouter as Router, Route, Switch } from 'react-router-dom';
import Home from './components/Home';
import Login from './components/Login';
import Dashboard from './components/Dashboard';
import NotFound from './components/NotFound';
const App = () => {
const [isLoggedIn, setIsLoggedIn] = useState(false);
return (
<Router>
<Switch>
<Route exact path="/" component={Home} />
<Route path="/login">
<Login setIsLoggedIn={setIsLoggedIn} />
</Route>
{isLoggedIn ? (
<Route path="/dashboard" component={Dashboard} />
) : (
<Route component={NotFound} />
)}
</Switch>
</Router>
);
};
export default App;
In this code, we are using the isLoggedIn
state to conditionally render either the Dashboard
component if the user is logged in, or the NotFound
component if the user is not logged in. The Login
component sets the isLoggedIn
state to true
once the user successfully logs in.
Note that we are using the <Route>
component’s children prop to pass in the Login
component and the setIsLoggedIn
function. This allows us to pass in props to the Login
component without specifying it in the path
prop.
Summary
Conditional rendering is a powerful technique in React that allows you to dynamically update the UI based on different conditions.
Depending on the complexity of your application’s UI logic, you can choose the approach that best fits your needs.
Remember to keep your code clean, organized, and readable, and always thoroughly test your conditional rendering logic to ensure it works as expected in different scenarios.
Looking for the ideal hosting solution for your React applications? Give Kinsta’s Application hosting a try for free!
Leave a Reply