All Articles

3 Ways to Conditionally Render Components in React using Hooks

Let’s say we have an App which allows logged in users to do stuff. When the user logs in, we’ll show them a “Welcome to the App!” message. If the user tries to visit our app, and isn’t logged in, we’ll show them a “Please sign up” message. These are the components that we need to render:

import React from 'react';

function UserGreeting(props) {
	return <h1>Welcome to the App!</h1>;
}

function GuestGreeting(props) {
	return <h1>Please sign up</h1>;
}

export default function App() {
	//...we need to do stuff in here to conditionally render components
}

1. Using an If Statement

The first approach we’ll look at is using a plain old if statement. Within our App component, we use an if statement to check if the user is logged in or not. If they are, we’ll return the UserGreeting component. If the user isn’t logged in, we’ll return the GuestGreeting component.

The code looks like this:

import React from 'react';

function UserGreeting(props) {
	return <h1>Welcome to the App!</h1>;
}

function GuestGreeting(props) {
	return <h1>Please sign up</h1>;
}

export default function App() {
	const isLoggedIn = false;
	if (isLoggedIn) {
		return <UserGreeting />;
	}
	return <GuestGreeting />;
}

Check out this example (App.js):

While this works, it’s quite verbose and if we want to add additional JSX to wrap these components (for example, another div) we need to repeat ourselves:

import React from 'react';

function UserGreeting(props) {
	return <h1>Welcome to the App!</h1>;
}

function GuestGreeting(props) {
	return <h1>Please sign up</h1>;
}

export default function App() {
	const isLoggedIn = false;
	if (isLoggedIn) {
		return;
		<div className='wrapper'>
			<UserGreeting />
		</div>;
	}
	return (
		<div className='wrapper'>
			<GuestGreeting />
		</div>
	);
}

Let’s look at how we can use the ternary operator to tidy this up a bit.

2. Using the ternary operator

You can think of the ternary operator as a shorthand if statement and looks like this:

condition ? code_to_run_if_true : code_to_run_if_false;

this reads as:

  • If the condiition is true, run the first code block (to the left of the colon).
  • If the condition is false, run the second code block (to the right of the colon).

With this in mind, let’s look at how our code would look now:

import React from 'react';

function UserGreeting(props) {
	return <h1>Welcome to the App!</h1>;
}

function GuestGreeting(props) {
	return <h1>Please sign up</h1>;
}

export default function App() {
	const isLoggedIn = false;
	return <div className='wrapper'>{isLoggedIn ? <UserGreeting /> : <GuestGreeting />}</div>;
}

Live example (App.js):

Now the code is much nicer - we don’t have to repeat ourselves if we want to add a another div. My glancing through the code we can reason about the logic - if isLoggedIn is true, UserGreeting gets rendered. Otherwise, GuestGreeting gets rendered.

3. Using the switch statement

So far we’ve looked at how to render “this OR that” using an if statement and the ternary operator. But what about if we have many components which we must decide to render? Let’s say we have a notification component, which can render 3 different components based on some variable.

For this, we can use the switch statement to determine what component needs to render:

import React from 'react';
import './styles.css';

function Info() {
	return <div style={{ background: 'lightblue' }}>This is an info alert!</div>;
}

function Warning() {
	return <div style={{ background: 'lightyellow' }}>This is a warning alert!</div>;
}

function Error() {
	return <div style={{ background: 'red' }}>This is an error alert! Panic!</div>;
}

function Notification(props) {
	switch (props.type) {
		case 'info':
			return <Info />;
		case 'warning':
			return <Warning />;
		case 'error':
			return <Error />;
		default:
			return null;
	}
}

export default function App() {
	return (
		<div className='App'>
			{/* Change the "type" to 'warning' and 'error' to see diferrent alert! */}
			<Notification type='error' />
		</div>
	);
}

Note how App.js calls a Notification component, passing in a type prop. The Notification component then uses a switch statement to return the appropriate component based on the type prop.

Live example (App.js):