Conditional Rendering in React

Conditional Rendering in React

Conditional Rendering in React 1280 720 Shuvo Habib

Conditional Rendering in React JS

What is Conditional Rendering?

When we are developing any kind of application whether in React or other JS frameworks, we need to show or hide elements based on certain conditions. It can be just a user interaction, say we need to show a popup when a user clicks a certain button and hide it when (s)he clicks the cross icon. Think another example regarding authentication, we make a ‘log out’ button visible when (s)he is logged in and ‘Login/Sign up’ form visible for the exact opposite situation. This is called conditional rendering.

In this article, we’ll be discussing conditional rendering in ReactJS and looking at different ways to handle those cases. We cover below the most useful methods for conditional rendering in react:

  • if/else
  • Ternary operation
  • Inline IF with Logical && operator
  • Switch case operator
  • Conditional Rendering with enums
  • Higher-Order Components

if/else

Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like if, and let React update the UI to match them. We use an if with our condition and return the element to be rendered. Let’s observe the example below:

Consider these two components:

LoggedInUser Component

function LoggedInUser(props) {
  return <div>
     <h1>Welcome back! </h1>
     <span>Log out </span>
   </div>;
}

LoggedOutUser Component

function LoggedOutUser(props) {
  return <div>
     <h1>Sign in, please! </h1>
     <span>Log out </span>
   </div>;
}

We’ll create a LoggedStatus component that displays either of these components depending on whether a user is logged in or not: isLoggedIn props will be true or false.

function LoggedStatus(props) {
  const isLoggedIn = props.isLoggedIn;
  if (isLoggedIn) {
    return <LoggedInUser />;
  }
return <LoggedOutUser />;
}
ReactDOM.render(
  <LoggedStatus isLoggedIn={false} />,
  document.getElementById('root')
);

This example renders a different greeting depending on the value of isLoggedIn prop. You can try changing the value of isLoggedIn prop to true.

isLoggedIn={true}:

Note that we DID NOT use ELSE since there is no need as we use the return within the first IF.

Ternary operation

The conditional (ternary) operator is the only JavaScript operator that takes three operands. This operator is frequently used as a shortcut for the if statement.

condition ? "This is True" : "This is False"

If condition can be converted to true, the operator returns “This is True”; otherwise (when condition is falsy) it returns “This is False”.

How can we use this in React JS?

Consider this situation – we need to show “Update” button when an edit has been done otherwise, we need to show “Edit” button.

render() {
  const edited = true;
  return (
    <div>
      {edited ? (
        <UpdateButton onClick={this.handleUpdateClick} />
      ) : (
        <EditButton onClick={this.handleEditClick} />
      )}
    </div>
  );
}

In this case, as edited is true, we’ll show the user Update button

Inline If with Logical && Operator

&& is a boolean operator, which means “and”. For it to evaluate to true, both of the statements must be true.

function TodoComponent(props) {
  const todoList = props.todoList;
  return (
    <div>
      <h1>Hi User!</h1>
      {todoList.length > 0 &&
        <h2>
          You have {todoList.length} Tasks to do.
        </h2>
      }
    </div>
  );
}
const todo = ['Eat', 'Play', 'Read'];
ReactDOM.render(
  <Task todoList={todo} />,
  document.getElementById('root')
);

In this case, Length of todo array is 3 that is large than 0, which is why it’ll print, “You have 3 Tasks to do.” If the length of todo array was 0, it’d have printed nothing.

Switch Case operator in React

We can write switch case inline just like normal Javascript for conditional rendering in React. Therefore you would need a self-invoking JavaScript function.

function Notification({ param }) {
  return (
    <div>
      {(function() {
        switch(param) {
         case 'foo':
          return 'bar';
         default:
          return 'foo';
         }
        }
      })()}
    </div>
  );
}

Note: You always have to use default for the switch case operator. In React, a component always needs to return an element or null.

To make it cleaner, get that switch out of the render in a function and just call it passing the params you want. For example:

renderSwitch(param) {
  switch(param) {
    case 'foo':
      return 'bar';
    default:
      return 'foo';
  }
}
render() {
  return (
    <div>
      {this.renderSwitch(param)}
    <div>
  );
}

In a nutshell, the switch case operator helps us to have multiple conditional renderings. But it may not be the best way to do that. Conditional renderings with enums is much more neat and readable compared to the switch case operator. Let’s see how we can have multiple conditional renderings with enums.

Conditional Rendering with enums

In JavaScript an object can be used as an enum when the object is used as a map of key value pairs.

const ENUMOBJECT = {
  a: '1',
  b: '2',
  c: '3',
};

Let’s dive into the example below. We’re creating three different components Foo, Bar and Default. We’ll be showing components respectively based on the state.

const Foo = () => {
  return <button>FOO</button>;
};
const Bar = () => {
  return <button>BAR</button>;
};
const Default = () => {
  return <button>DEFAULT</button>;
};

We’ll be creating an object, that can be used as an enum.

const ENUM_STATES = {
  foo: <Foo />,
  bar: <Bar />,
  default: <Default />
};

Now, we will create a function that will take state as a parameter and will be returning components based on state. This EnumState function is pretty much self-explanatory.

function EnumState({ state }) {
  return <div>{ENUM_STATES[state]}</div>;
}

The state property key helps us to retrieve the value from the object. It is much more readable compared to the switch case operator.

We’re creating an Enum component, which will be passing the values of state to the function EnumState

class Enum extends React.Component {
  render() {
    return (
      <div>
        <h1>Conditional Rendering with enums</h1>
        <EnumState state="default"></EnumState>
        <EnumState state="bar"></EnumState>
        <EnumState state="foo"></EnumState>
      </div>
    );
  }
}
ReactDOM.render(<Enum />, document.getElementById("app"));

Codepen Example: https://codepen.io/ShuvoHabib/pen/OrzLwE

After all, the enum approach in comparison to the switch case statement is more readable. Objects as enum open up a plethora of options to have multiple conditional renderings.

Higher Order Components

Higher order components, or known under the abbreviation HOCs, are often a difficult pattern to grasp in ReactJS. These components can be used for multiple use cases. In this article, we’ll be picking up HOC for conditional rendering.

HOCs are a perfect match for conditional rendering in React. They can have several use cases. One use case could be to alter the look of a component. To make it more specific: it could be used to apply conditional rendering for a component. Let’s have a look at a HOC that either shows a loading indicator or the desired component.

// HOC declaration
function withLoading(Component) {
  return function EnhancedComponent({ isLoading, ...props }) {
    if (!isLoading) {
      return <Component { ...props } />;
    }
    return <div><p>Loading...</p></div>;
  };
}
// Usage
const ListWithLoading= withLoading(List);
<ListWithLoading
  isLoading={props.isLoading}
  list={props.list}
/>

In the above example, the List component can focus on rendering the list. It doesn’t have to bother about a loading state. Ultimately we could add more higher order components to shield away multiple conditional rendering edge cases.

In conclusion, I believe you can make use of any listed alternatives for conditional rendering. Based on your use case, you need to apply the one that works best.

Shuvo Habib

Storyteller about JavaScript, new Frontend dev technologies, and A/B testing