Jan 25, 2023
Anshuman Bhardwaj
Learn how conditional rendering is used to show a personalized UI, complete a user flow without changing routes, or show a loading or error state.
Conditional rendering is a pattern used in React to render a different user interface (UI) based on whether a condition is true
or false
. This can be as simple as rendering a loading message while waiting for an API to return the data, where the loading message is conditionally rendered based on whether the loading is true
or false
.
Conditional rendering is quite helpful for showing a personalized UI based on the user's preference, completing a user flow without changing routes, or showing a loading or error state.
In this article, you'll learn about different conditional rendering methods in React applications. You'll use the Clerk client for React to implement a simple dashboard application that conditionally shows the UI based on whether or not the user is signed in.
Conditional rendering in React allows you to implement interactive interfaces where you render different UIs based on the application state; these can range from user inputs to user preferences. Let's dig into conditional rendering with some practical use cases.
This can be based on your preference as a user and is one of the most common uses you'll see out there. Consider Twitter, for example. You'll only see the Explore section if you're not signed in to Twitter.
When you're signed in, you'll see a personalized feed in sections like Home and Messages.
This is another use case for conditional rendering. Consider Typeform, for example. The application has multiple pages in a single form, but rather than navigating to a new page for every question, it uses conditional rendering to show only the current question.
This is essential for any application dealing with data loading. Consider Twitter again. See how Home and Trending both show a loader while fetching the feed.
There are a few ways to do conditional rendering in React, and you'll learn about five of them in this article. You can follow the examples by setting up this GitHub repository on your local drive.
You can use the good old if…else
conditional statement in JavaScript. You can use the if
condition to return a certain JSX if the user is signed in and something else if they aren't.
1// AppWithIf.jsx23function App() {4const isLoggedIn = true;5if (isLoggedIn) {6return <div className="App">Hello, logged in user!</div>;7} else {8return <div>User not logged in!</div>;9}10}1112export default App;
The conditional (ternary) operator can also be used to check whether the user is signed in and return components accordingly.
The ternary operator is a good choice if you've abstracted your JSX into components:
1// AppWithTernary.jsx23function SignedIn() {4return <div className="App">Hello, logged in user!</div>;5}67function SignedOut() {8return <div>User not logged in!</div>;9}1011function App() {12const isLoggedIn = true;13return isLoggedIn ? <SignedIn /> : <SignedOut />;14}1516export default App;
The switch case is useful when you want to conditionally render a component based on a range of choices—for example, if you're conditionally rendering the component based on the user's permission level, as shown below:
1// AppWithSwitch.jsx23function Viewer() {4return <div className="App">Hello, logged in as Viewer!</div>;5}67function SignedOut() {8return <div>User not logged in!</div>;9}1011function Admin() {12return <div className="App">Hello, logged in as Admin!</div>;13}1415function Editor() {16return <div className="App">Hello, logged in as Editor!</div>;17}1819function App() {20const userPermission = "admin";21switch (userPermission) {22case "viewer":23return <Viewer />;24case "editor":25return <Editor />;26case "admin":27return <Admin />;28default:29return <SignedOut />;30}31}3233export default App;
An IIFE is a good option if you want to use the conditional statement within the return
statement. In this example, the anonymous function below the h1
tag runs on every render and returns the JSX based on the user's login state:
1// AppWithIIFE.jsx23function App() {4const isLoggedIn = true;5return (6<div>7<h1>Amazing application</h1>8{(function () {9if (isLoggedIn) {10return <div className="App">Hello, logged in user!</div>;11} else {12return <div>User not logged in!</div>;13}14})()}15</div>16);17}1819export default App;
A higher-order component (HOC) is a pattern for reusing component logic. You can use a HOC to abstract the authentication logic with multiple components. In this example, the withAuth
function is a HOC that takes a component as input and returns another component with conditional rendering based on the user's login state:
1// AppWithHOC.jsx23import { useEffect, useState } from "react";45async function getUserAuth() {6// get Auth state from somewhere7return true8}910function withAuth(Component) {11return function ComponentWithAuth() {12const [isLoggedIn, setLoggedIn] = useState(true);13useEffect(() => {14getUserAuth().then((auth) => setLoggedIn(auth));15}, []);16return isLoggedIn ? <Component /> : <div>Please log in to view this component.</div>;17};18}1920function Dashboard({ }) {21return (22<div>23<h1>Amazing application</h1>24<p>Best dashboard</p>25</div>26);27}2829const DashboardWithAuth = withAuth(Dashboard);3031function App() {32return <DashboardWithAuth />;33}3435export default App;
You've now learned about different ways of using conditional rendering for authentication. You can see that dealing with authentication can get very messy: the more auth state you manage, the more complex the conditionals become. What if there was an authentication provider that takes care of all the conditional rendering for you?
Next you'll see how the Clerk frontend client can be used to implement conditional rendering based on the user's authentication state.
Run the following command in your terminal to create a new React project:
1npx create-react-app clerk-react-conditionals
Navigate to the newly made project in your terminal by running the following:
1cd clerk-react-conditionals
Now install the Clerk React client using the following command:
1npm install @clerk/clerk-react
Log in to your Clerk dashboard and copy the frontend API key from the API keys page.
Create the new file .env.local and securely save the frontend API key like so:
1REACT_APP_CLERK_FRONTEND_API=<paste-the-key-from-clerk-dashboard>
Note: Don't commit the .env.local file to keep the key safe.
In the App.js file, add the ClerkProvider
at the top level in the App
component. Pass the ClerkProvider
with the frontendApi
prop from the environment variables. The ClerkProvider
provides the authentication state and methods to all the child components:
1import React from "react";2import {3ClerkProvider,4SignedIn,5SignedOut,6SignOutButton,7SignInButton,8useUser,9} from "@clerk/clerk-react";1011const frontendApi = process.env.REACT_APP_CLERK_FRONTEND_API;1213function App() {14return (15<ClerkProvider frontendApi={frontendApi}>16<SignedIn>17<p style={{ padding: 20 }}>Welcome to the amazing dashboard!</p>18</SignedIn>19<SignedOut>20<p style={{ padding: 20 }}>21You must be signed in to use the dashboard.22</p>23</SignedOut>24</ClerkProvider>25);26}
The SignedIn
and SignedOut
components from Clerk conditionally render the children. The SignedIn
component renders children if the user is signed in, and the SignedOut
component renders children if they're not. This example renders different messages, but you can use any other component according to your application.
Run npm start
in your terminal to start the application and open http://localhost:3000 in a web browser. You should see the following message.
The dashboard conditionally renders different messages based on a user's sign-in state, but the user still needs the option to sign in. As a good practice, you can put the Sign in and Sign out buttons at the top NavBar
component:
1import React from "react";2import {3ClerkProvider,4SignedIn,5SignedOut,6SignOutButton,7SignInButton,8useUser,9} from "@clerk/clerk-react";1011function NavBar() {12const { user, isSignedIn } = useUser();13return (14<nav15style={{16display: "flex",17justifyContent: "space-between",18alignItems: "center",19padding: "10px 20px",20backgroundColor: "peachpuff",21}}22>23<h2>Amazing dashboard</h2>24{isSignedIn ? (25<div style={{ display: "flex", alignItems: "center" }}>26<p style={{ marginRight: 10 }}>Hello, {user.firstName}!</p>27<SignOutButton />28</div>29) : (30<SignInButton />31)}32</nav>33);34}
The NavBar
component uses the useUser
hook from Clerk to get the user
object and isSignedIn
Boolean flag. The component renders a navbar with an h2
"Amazing dashboard" and, depending on the value of isSignedIn
, displays either a greeting with the user's first name and a SignOutButton
component or a SignInButton
component.
Now use the NavBar
component in the App
. The final application code should look as shown below:
1import React from "react";2import {3ClerkProvider,4SignedIn,5SignedOut,6SignOutButton,7SignInButton,8useUser,9} from "@clerk/clerk-react";1011const frontendApi = process.env.REACT_APP_CLERK_FRONTEND_API;1213function App() {14return (15<ClerkProvider frontendApi={frontendApi}>16<NavBar />17<SignedIn>18<p style={{ padding: 20 }}>Welcome to the amazing dashboard!</p>19</SignedIn>20<SignedOut>21<p style={{ padding: 20 }}>22You must be signed in to use the dashboard.23</p>24</SignedOut>25</ClerkProvider>26);27}2829function NavBar() {30const { user, isSignedIn } = useUser();31return (32<nav33style={{34display: "flex",35justifyContent: "space-between",36alignItems: "center",37padding: "10px 20px",38backgroundColor: "peachpuff",39}}40>41<h2>Amazing dashboard</h2>42{isSignedIn ? (43<div style={{ display: "flex", alignItems: "center" }}>44<p style={{ marginRight: 10 }}>Hello, {user.firstName}!</p>45<SignOutButton />46</div>47) : (48<SignInButton />49)}50</nav>51);52}5354export default App;
Your secured dashboard application can be seen in action below.
After completing this tutorial, you'll have successfully built a secured dashboard application that conditionally renders specific UIs according to the user's sign-in state. While doing so, you learned about different ways of conditionally rendering the UI in React. You also discovered various components and hooks that Clerk provides to render UIs conditionally depending on the user's authentication status.
Clerk is a complete user management solution with pre-built components, hooks, and even a user interface for user profile management. Clerk is an easy-to-integrate solution for your React applications with first-class support for all modern frameworks such as Next.js, Remix, and RedwoodJS. Give Clerk a try for free to explore a complete list of its features.
Start completely free for up to 5,000 monthly active users and up to 10 monthly active orgs. No credit card required.
Learn more about our transparent per-user costs to estimate how much your company could save by implementing Clerk.
The latest news and updates from Clerk, sent to your inbox.