DEV Community

Cover image for React Conditional Rendering Best Practices with 7 Different Methods
Syakir
Syakir

Posted on • Edited on • Originally published at devaradise.com

React Conditional Rendering Best Practices with 7 Different Methods

This post was originally published at https://www.devaradise.com/react-conditional-rendering-if-else

In React, conditional rendering can be done in many ways depend on contexts. In this post, we're going to discuss all of the methods that we can use to write better code for conditional rendering in React.

~~

Conditional Rendering is a common feature that exists in every programming language, including javascript. In javascript, we usually write conditional rendering with "if else" statement, "switch case" statement, and ternary operator.

All of these methods are applicable to React. But the question is, How we can use them effectively?

As you might know, React has JSX markup that often we need to implement conditional logic for component there. However, we can't use common "if else" or "switch case" statement directly in JSX.

In JSX, we should use other conditional rendering methods like the ternary operator and && operator. Here, we are going to discuss this more details.

Related posts:

~~

At least, there are 7 methods of conditional rendering that we can use in React. Each one of them has its own advantage in some contexts.

Table of Contents

1. Conditional Rendering with If Else

Best Practices Summary

  • Use anywhere outside JSX markup
  • Or when you want to execute more than one line of code inside if-else block

~~

This is the first method that all programmers know, the common if-else statement. We can use it anywhere in a React project.

In React, using the common if-else statement is the best when you want to execute more than one line of code inside if or else block, or anywhere outside JSX.

For example, we want to execute some codes if user is logged in.

  // * Conditional rendering with common if-else statement.
  if(isLoggedIn) {
    setUserProfile(userData);
    setUserHistory(userHistory);
    // other block of codes;
  }
Enter fullscreen mode Exit fullscreen mode

Or when you want to define accessible contents based of user role.

  if(userProfile.role === 'superadmin') {
    initSuperAdminFunction();
    initSuperAdminComponent();
    // other block of codes;
  } else if(userProfile.role === 'admin') {
    initAdminFunction();
    initAdminComponent();
    // other block of codes;
  } else {
    initUserComponent();
    // other block of codes;
  }
Enter fullscreen mode Exit fullscreen mode

if you only want to execute one line of code, like calling a function inside if or else block, you can remove the brackets like this.

if(userProfile.role === 'superadmin')
    initSuperAdminComponent();
else if(userProfile.role === 'admin')
    initAdminFunction();
else 
    initUserComponent();

Enter fullscreen mode Exit fullscreen mode

Condition in if-else without brackets only applied to one line of codes right below it.

If else statement in JSX

As you might know, we can inject and mix some javascript codes in JSX inside brackets { }. But it has some limitations.

You can't inject if-else statement directly to it. Injecting if-else statement in JSX only works with Immediately Invoked Function Expression (IIFE) like this:

return(
    <div>
      { 
        (() => {
          if(isLoggedIn) {
            return (<div>I'm logged in.</div>);
          }
        })()
      }
    </div>
)
Enter fullscreen mode Exit fullscreen mode

As you can see, that's too verbose for just an if statement. That's why i don't recommend using if-else statement inside JSX.

There are some other ways for conditional rendering in JSX, just keep reading.

2. Conditional Rendering with Ternary Operator

Best practices Summary

  • Use it to assign value for a conditional variable or function return value
  • Or when you want to execute only one line of code
  • Or for conditional rendering in JSX

~~

Ternary operator is a shortcut for a common if-else statement. With ternary operator, you can write the conditional rendering inline, or in only one line of code.

Let’s see the example of conditional rendering for variable value assignment.

  // Conditional rendering with common if else
  let isDrinkCoffee;
  if(role === 'programmer') {
    isDrinkCoffee = true;
  } else {
    isDrinkCoffee = false;
  }

  // Conditional rendering with ternary operator
  let isDrinkCoffee = (role === 'programmer') ? true : false;
Enter fullscreen mode Exit fullscreen mode

And this is conditional rendering example for function return value:

// Conditional rendering with common if else
  function isDrinkCoffee(role) {
    if(role === 'programmer') {
      return true;
    } else {
      return false;
    }
  }

  // Conditional rendering with ternary operator
  function isDrinkCoffee(role) {
    return role === 'programmer' ? true : false;
  }
Enter fullscreen mode Exit fullscreen mode

As you can see, you can shorten if-else statement with just one line with ternary operator.

You can also use ternary operator in JSX instead of using if-else with Immediately Invoked Function Expression (IIFE).

Let's say, we want to render a small component conditionally based on isShow state. You can write the conditional rendering like this.

return (
  <div>
     { isShow ? <SmallComponent/> : null }
  </div>
)
Enter fullscreen mode Exit fullscreen mode

if - else if - else with Ternary Operator

In the example above I only show you how to use a ternary operator to substitute if-else statement.

Ternary operator can also be used to substitute multiple conditional rendering (if - else if - else) or nested conditional rendering.

However, I don't recommend you to use this as it's harder to read than a common if-else statement.

Let' say you want to implement nested conditional rendering in JSX.

return (
  <div>
    { condition_a
      ? <ComponentA/>
      : ( condition_b
        ? <ComponentB/>
        : ( condition_c
          ? <ComponentC/>
          : <ComponentD/>
        )
      )
    }
  </div>
);
Enter fullscreen mode Exit fullscreen mode

Look messy, right?

For cases like this, using IIFE, switch-case statement or enum object is better than the ternary operator.

3. Conditional Rendering with Short-circuit && Operator

Best practice Summary

  • Use it for a simple conditional rendering that no need to execute code in the 'else' block.

~~

With ternary operator, you can shorten if-else statement and have better choice for conditional rendering in JSX.

But, do you know that there is a simpler method than ternary operator?

A Short-circuit AND Operator can be used to replace an if statement like this.

// Instead of using ternary operator,
{ isShow ? <SmallComponent/> : null }

// Use short-circuit &amp;&amp; operator
{ isShow &amp;&amp; <SmallComponent/> }
Enter fullscreen mode Exit fullscreen mode

In Ternary operator, even when you have no 'else' condition, you should keep write ': null' expression to avoid error.

With short-circuit && operator, you don't have to do that.

But, keep in mind that short-circuit && operator can not be used to substitute an if-else statement, let alone an if-else if-else statement.

4. Multiple Conditional Rendering with Switch - Case

Best Practices Summary

  • Use it anywhere for multiple conditional rendering that only has one variable to evaluate condition.

~~

Like if-else statement, switch-case statement is also a common feature in almost every programming language.

It is used for multiple conditional rendering with the same type of condition.

For example, we can use a switch-case statement to render a specific variable value based on user roles.

let welcomeMessage;
switch(role) {
  case 'superadmin':
    welcomeMessage = 'Welcome Super Admin';
    // you can put other codes here as well.
  case 'admin':
    welcomeMessage = 'Welcome Admin';
    // you can put other codes here as well.
  case 'user':
    welcomeMessage = 'Welcome User';
    // you can put other codes here as well.
  default:
    welcomeMessage = 'Welcome Guest';
    // you can put other codes here as well.
}
Enter fullscreen mode Exit fullscreen mode

You can also use a switch-case statement for conditional rendering in JSX. However, you should wrap it inside IIFE.

Suppose that you want to render an alert component that styled based on the alert status.

return (
  <div>
    { 
      (() => {
        switch(status) {
          case 'warning':
            return <AlertComponent status="warning" message={messageState}/>;
          case 'error':
            return <AlertComponent status="error" message={messageState}/>;
          case 'success':
            return <AlertComponent status="success" message={messageState}/>;
          default:
            return <AlertComponent status="info" message={messageState}/>;
        }
      })()
    }
  </div>
)
Enter fullscreen mode Exit fullscreen mode

As you might have noticed, both examples have only one variable (role and status) to evaluate conditions. This is what I called the same type of conditions before.

Switch-case statement can not be used to handle a complex and different type of conditions. Instead, you should use a common if-else if-else statement for that.

5. Multiple Conditional Rendering with Enum Object

Best Practices Summary

  • Use it only when you want to assign variable value or return value with multiple conditions.

~~

Enum objects can also be used to implement multiple conditional rendering in React. It is the better alternative for switch-case statements in JSX markup.

As you know before in the 5th method, you should wrap the switch-case statement inside IIFE in JSX. With an enum object, you don't need to do that.

Let's take the same example as before. You want to render an alert component based on status. Here is how you conditionally render it using an enum object.

const ALERT_STATUS = {
  warning: <AlertComponent status="warning"/>,
  error: <AlertComponent status="error"/>,
  success: <AlertComponent status="success"/>,
  info: <AlertComponent status="info"/>
}

return (
  <div>
    { ALERT_STATUS[status] }
  </div>
)
Enter fullscreen mode Exit fullscreen mode

As you can see, you need to create an enum object first called 'ALERT_STATUS'. Then, simply call it in JSX with status variable inside elbow bracket that has value 'warning', 'error', 'success' or 'info'.

If the <AlertComponent/> need other props or attributes to be passed, you can change ALERT_STATUS to a function like this.

const ALERT_STATUS = (message) => ({
  warning: <AlertComponent status="warning" message={message}/>,
  error: <AlertComponent status="error" message={message}/>,
  success: <AlertComponent status="success" message={message}/>,
  info: <AlertComponent status="info" message={message}/>
})

return (
  <div>
    { ALERT_STATUS(messageState)[status] }
  </div>
)
Enter fullscreen mode Exit fullscreen mode

You can also assign the alert component to a variable.

let newVariable = ALERT_STATUS(messageState)[status];
Enter fullscreen mode Exit fullscreen mode

Of course, you should define the enum object first.

Separating Enum object as file to make it reusable

The best thing about using an Enum object for conditional rendering is that you can make it reusable.

Back to the example case, the Alert component is a component in React that usually reusable. So, you can also make it reusable when you want to render it conditionally.

You can define the enum in seperate file and export it like this.

import React from 'react';
import AlertComponent from './path/to/AlertComponent';

export const ALERT_STATUS = (message) => ({
  warning: <AlertComponent status="warning" message={message}/>,
  error: <AlertComponent status="error" message={message}/>,
  success: <AlertComponent status="success" message={message}/>,
  info: <AlertComponent status="info" message={message}/>
})
Enter fullscreen mode Exit fullscreen mode

Then, import it when you want to use it in a component.

import { ALERT_STATUS } from './alertStatus'
Enter fullscreen mode Exit fullscreen mode

The usage is the same as before.

6. Conditional Rendering with HOC

Best Practices Summary

  • Use it when you want to implement or check some conditions before rendering a component.

~~

Higher Order Component (HOC) can be used to implement conditional rendering in React. You can use it when you want to run some logic or checking before rendering a component.

For example, you want to check if the users are authenticated before they access some components.

Instead of writing if-else statement in every component that needs authentication, you can use HOC to guard those component.

// This is Higher Order Component
import React from 'react'
export default function withAuthentication(Component) {

  // some code of authentication logic/service that result an isLoggedIn variable/state:
  let isLoggedIn = true;

  return function AuthenticatedComponent(props) {
    if(isLoggedIn) {
      return <Component {...props}/>
    } else {
      return (<div class="alert alert-danger">You're not authenticated!</div>);
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Then, you can import and use it in a component.

import withAuthentication from './withAuthentication'
Enter fullscreen mode Exit fullscreen mode
const AuthenticatedUIComponent = withAuthentication(AnUIComponent);

return (
  <div>
    <AuthenticatedUIComponent/>
  </div>
)
Enter fullscreen mode Exit fullscreen mode

That's better, right?

You can use HOC for other reusable conditional rendering like loading indicator implementation, null checking, etc.

To more details about HOC (with functional component), you can read this article on medium.

7. JSX Conditional Rendering with External Library

Best Practices Summary

  • Avoid using this method. Be familiar with the 6 methods above :D

~~

Though I wouldn't recommend you using this method, I just want to let you know that there is a babel plugin that makes JSX have its own conditional rendering tags.

with JSX Control Statements, you can write conditional rendering in JSX like this.


<If condition={test}>
  <span>Truth</span>
</If>;

<Choose>
  <When condition={ test1 }>
    <span>IfBlock</span>
  </When>
  <When condition={ test2 }>
    <span>ElseIfBlock</span>
    <span>Another ElseIfBlock</span>
    <span>...</span>
  </When>
  <Otherwise>
    <span>ElseBlock</span>
  </Otherwise>
</Choose>
Enter fullscreen mode Exit fullscreen mode

In the compilation, those tags will be transformed into ternary operators.

Some developers use this plugin because it looks more readable for conditional rendering in JSX.

~~

That's all the 7 methods you can use for conditional rendering in React.

Do you know other methods for conditional rendering in React? or some thoughts about the methods above?

Feel free to suggest it in the comment below!

Happy coding!

Top comments (2)

Collapse
 
lexlohr profile image
Alex Lohr

Small nitpick about your example:

const ALERT_STATUS = (message) => ({
  warning: <AlertComponent status="warning" message={message}/>,
  error: <AlertComponent status="error" message={message}/>,
  success: <AlertComponent status="success" message={message}/>,
  info: <AlertComponent status="info" message={message}/>
})

let newVariable = ALERT_STATUS(messageState)[status];

will create all the components virtual dom initialized with the message. This may not be too much of a performance issue, but could potentially trigger side effects. It would therefore be better to use

const ALERT_STATUS = {
  warning: (message) => <AlertComponent status="warning" message={message}/>,
  error: (message) => <AlertComponent status="error" message={message}/>,
  success: (message) => <AlertComponent status="success" message={message}/>,
  info: (message) => <AlertComponent status="info" message={message}/>
}

let newVariable = ALERT_STATUS[status](messageState);
Collapse
 
syakirurahman profile image
Syakir • Edited

Thanks for your correction! :)
I dont consider about that. Will update it later.