The original link: www.robinwieruch.de/conditional… By Robin Wieruch

Using conditional rendering in React is not difficult. In JSX — the syntax extension for React — you can use pure JavaScript, which includes if else statements, ternary operators, switch case statements, and so on. In conditional rendering, the React component decides which DOM elements to return based on one or more conditions. For example, based on some logic, it could return a list of items or text that says “Sorry, list is empty.” When a component is rendered conditionally, the rendered component looks different depending on the condition. This article aims to provide an exhaustive list of options for conditional rendering in React and best practices for these modes.

directory

  • React Conditional render: if
  • React Conditional render: if else
  • React Conditional render: ternary
  • React Conditional render: &&
  • React Conditional render: Switch case
  • React Multi-conditional rendering
  • React nested conditional rendering
  • Conditional rendering using HOC
  • React if else component

React Conditional render: if

The most basic conditional rendering logic in React is done with an if statement. Suppose you don’t want to render something in the React component because it doesn’t have the necessary React props available. For example, the List component in React should not render the HTML elements of the list in the view if there is no list to begin with. You can use a simple JavaScript if statement to return early (guard mode) :

const users = [
  { id: '1'.firstName: 'Robin'.lastName: 'Wieruch' },
  { id: '2'.firstName: 'Dennis'.lastName: 'Wieruch'},];function App() {
  return( <div> <h1>Hello Conditional Rendering</h1> <List list={users} /> </div> ); } function List({ list }) { if (! list) { return null; } return ( <ul> {list.map(item => ( <Item key={item.id} item={item} /> ))} </ul> ); } function Item({ item }) { return ( <li> {item.firstName} {item.lastName} </li> ); }Copy the code

You can try setting the user to NULL or undefined yourself. If the information in props is null or undefined, the React component returns NULL in the conditional rendering. Here, the React component that returns NULL instead of JSX will render nothing.

In this example, we have done conditional rendering based on props, but conditional rendering can also be based on state and hooks. Note that we have not used the if statement internally within JSX, but only externally before the return statement.

React Conditional render: if else

Let’s continue with the previous example to learn about the if else statement in React. Without the list, we render nothing and hide the HTML, as we saw earlier with a single if statement. However, for a better user experience, you might want to display a text for the user as feedback when the list is empty. This will be used with another if statement, but we’ll extend the example with an if else statement:

function List({ list }) {
  if(! list) {return null;
  }
  if(! list.length) {return <p>Sorry, the list is empty.</p>;
  } else {
    return (
      <div>
        {list.map(item => (
          <Item item={item} />
        ))}
      </div>); }}Copy the code

Now, the List component does not render any content, text, or List according to some JavaScript logic. Although the previous example shows how to use if else statements in React, I recommend using a single if statement (here: return list) every time you need to protect the main return content as a best practice:

function List({ list }) {
  if(! list) {return null;
  }
  if(! list.length) {return <p>Sorry, the list is empty.</p>;
  }
  return (
    <div>
      {list.map(item => (
        <Item item={item} />
      ))}
    </div>
  );
}
Copy the code

This is more readable than the previous if else conditional rendering. All guards are neatly arranged in the if statement that precedes the main return statement, which can also be interpreted as the implied else statement. However, if and else statements are not used in return statements.

React Conditional render: ternary

Sure, we can use JavaScript in JSX, but using if, else, switch case statements in JSX can be difficult. There’s no real way to inline it. Another way to express an if else statement in JavaScript is the ternary operator:

// if else
function getFood(isVegetarian) {
  if (isVegetarian) {
    return 'tofu';
  } else {
    return 'fish'; }}// ternary operator
function getFood(isVegetarian) {
  return isVegetarian ? 'tofu' : 'fish';
}
Copy the code

For example, suppose your component displays preview or edit mode. The condition is a JavaScript Boolean in the form of React Prop. You can use booleans to determine which element you want to conditionally render:

function Recipe({ food, isEdit }) {
  return (
    <div>
      {food.name}
      {isEdit ? (
        <EditRecipe food={food} />
      ) : (
        <ShowRecipe food={food} />
      )}
    </div>
  );
}
Copy the code

The parentheses () around the two implicit return statements in the ternary operator enable you to return single or more HTML elements, or from there the React component. If there is only one element, you can omit the parentheses.

Note: Sometimes you need to wrap multiple lines of elements in a single div element as a block. Either way, try to keep it light. If the contents of the wrap between () are too large, consider extracting it as a component, as shown in the example.

Using ternary rendering in React not only makes conditional rendering simpler, but also gives you an easy way to embed conditional rendering in your returns. Thus, only part of JSX is rendered conditionally, while the rest can be left intact without any conditions.

React Conditional render: &&

It often happens that you want to render an element or nothing at all. You already know that a simple if condition can help solve this problem. However, you still want to be able to inline conditions like ternary operators. Use the following load indicator component, which returns an element using the conditional ternary operator or nothing at all:

function LoadingIndicator({ isLoading }) {
  return <div>{isLoading ? <p>Loading...</p> : null}</div>;
}
Copy the code

Well done, you inlined the conditions in your JSX. However, there is an alternative to omitting the need to return NULL.

The logical && operator helps you make the conditions for returning NULL more concise. In JavaScript, a true && Hello World always equals Hello World. False && Hello World always evaluates to False:

const result = true && 'Hello World';
console.log(result);
// Hello World
const result = false && 'Hello World';
console.log(result);
// false
Copy the code

In React, you can take advantage of this behavior. If the condition is true, the expression following the logical && operator is output. If the condition is false, React ignores and skips the expression:

function LoadingIndicator({ isLoading }) {
  return <div>{isLoading && <p>Loading...</p>}</div>;
}
Copy the code

This is your way when you want to return nothing or elements in JSX. It is also known as short-circuit evaluation, which makes it even more concise than the ternary operator.

React Conditional render: Switch case

It is now possible to have multiple conditional renders. For example, the notification component renders an error, warning, or information component based on a status string:

function Notification({ text, status }) {
  if (status === 'info') {
    return <Info text={text} />;
  }
  if (status === 'warning') {
    return <Warning text={text} />;
  }
  if (status === 'error') {
    return <Error text={text} />;
  }
  return null;
}
Copy the code

You can use the Switch case operator to handle multiple conditional renderings:

function Notification({ text, status }) {
  switch (status) {
    case 'info':
      return<Info text={text} />; case 'warning': return <Warning text={text} />; case 'error': return <Error text={text} />; default: return null; }}Copy the code

It is advisable to use default for the Switch case operator because the React component must always return an element or NULL. If a component has a conditional rendering based on strings, it makes sense to describe the component’s interface in TypeScript:

type Status = 'info' | 'warning' | 'error'; type NotificationProps = { text: string; status: Status; }; function Notification({ text, status }: NotificationProps) { switch (status) { case 'info': return <Info text={text} />; case 'warning': return <Warning text={text} />; case 'error': return <Error text={text} />; default: return null; }}Copy the code

Switch Case writing is a good place to start for multiple conditional rendering. But it has the same disadvantages as the if else statement. You can’t use switch case in JSX, right? It can actually be done with a conditional render function, which is self-called:

function Notification({ text, status }) {
  return (
    <div>
      {(function() {
        switch (status) {
          case 'info':
            return <Info text={text} />;
          case 'warning':
            return <Warning text={text} />;
          case 'error':
            return <Error text={text} />;
          default:
            return null;
        }
      })()}
    </div>
  );
}
Copy the code

Optionally use the conditional render arrow function to make the switch case more concise:

function Notification({ text, status }) {
  return (
    <div>
      {(() => {
        switch (status) {
          case 'info':
            return <Info text={text} />;
          case 'warning':
            return <Warning text={text} />;
          case 'error':
            return <Error text={text} />;
          default:
            return null;
        }
      })()}
    </div>
  );
}
Copy the code

In summary, the Switch Case operator can help you achieve multiple conditional rendering. But is this the best way? Let’s see how enumerations can be used instead of multiple conditional renderings.

React Multi-conditional rendering

JavaScript objects with mapped key-value pairs are called enumerations:

const NOTIFICATION_STATES = {
  info: 'Did you know? . '.warning: 'Be careful here ... '.error: 'Something went wrong ... '};Copy the code

Enumerations are a great way to handle conditional rendering with multiple conditions in React. They are more powerful than switch Case statements because they can be used in JSX. Let’s consider the notification component again, but this time using enumerations as inline objects (inside curly braces) :

function Notification({ text, status }) {
  return (
    <div>
      {
        {
          info: <Info text={text} />,
          warning: <Warning text={text} />,
          error: <Error text={text} />,
        }[status]
      }
    </div>
  );
}
Copy the code

The Status property key helps us retrieve values from the object. Great, isn’t it? It is much more readable than the Switch Case write operator.

In this case, we must use an inline object because the value of the object depends on the text property. Anyway, this is the way I recommend it. However, if it doesn’t depend on the text property, you can use an enumeration as a constant for conditional rendering:

const NOTIFICATION_STATES = {
  info: <Info />,
  warning: <Warning />,
  error: <Error />}; function Notification({ status }) { return (<div>
      {NOTIFICATION_STATES[status]}
    </div>
  );
}
Copy the code

That settles the matter. If we still rely on the previous text property, we can use a conditional render with a function to retrieve the value:

const getNotification = text= > ({
  info: <Info text={text} />,
  warning: <Warning text={text} />,
  error: <Error text={text} />,
});
function Notification({ status, text }) {
  return <div>{getNotification(text)[status]}</div>;
}
Copy the code

After all, enumeration conditional rendering in React is more elegant than switch Case statements. Objects as enumerations provide a number of options for implementing multiple conditional rendering. Boolean permutations are also possible:

function Message({ isExtrovert, isVegetarian }) {
  const key = `${isExtrovert}-${isVegetarian}`;
  return (
    <div>
      {
        {
          'true-true': <p>I am an extroverted vegetarian.</p>,
          'true-false': <p>I am an extroverted meat eater.</p>,
          'false-true': <p>I am an introverted vegetarian.</p>,
          'false-false': <p>I am an introverted meat eater.</p>,
        }[key]
      }
    </div>
  );
}
Copy the code

This last example is a bit over the top and I don’t recommend using it. However, when it comes to conditional rendering, enumeration is one of my favorite React modes.

React nested conditional rendering

What about nested conditional rendering in React? Yes, it is possible. For example, let’s look at the previous List component, which showed a List, an empty text, or nothing at all:

function List({ list }) {
  constisNotAvailable = ! list;constisEmpty = ! list.length;return (
    <div>
      {isNotAvailable
        ? <p>Sorry, the list is not there.</p>
        : (isEmpty
          ? <p>Sorry, the list is empty.</p>
          : <div>{list.map(item => <Item item={item} />)}</div>)}</div>
  );
}
Copy the code

It works, but I recommend avoiding nested conditional renderings because they are verbose, which makes it less readable. Try these solutions:

  • Use guard mode for if statements only before the main return statement
  • Components are split into components, each of which is responsible for its own non-nested conditional rendering

Conditional rendering using HOC

Higher-order Components (HOCs) are a perfect match for conditional rendering in React. Hoc can help with multiple usage scenarios, but one scenario might use conditional rendering to change the appearance of a component. Let’s look at a HOC that displays an element or component:

// Higher-Order Component
function withLoadingIndicator(Component) {
  return function EnhancedComponent({ isLoading, ... props }) {
    if(! isLoading) {return<Component {... props} />; } return ( <div> <p>Loading</p> </div> ); }; } const ListWithLoadingIndicator = withLoadingIndicator(List); function App({ list, isLoading }) { return ( <div> <h1>Hello Conditional Rendering</h1> <ListWithLoadingIndicator isLoading={isLoading} list={list} /> </div> ); }Copy the code

In this example, the List component can focus on rendering the List. It doesn’t have to worry about loading state. A HOC hides all the noise in your actual component. Finally, you can add multiple higher-order components (combos) to hide multiple conditional rendering edge cases. As an alternative to hoc, you can also use Render Prop to support conditional rendering.

React if else component

Last but not least, there are external libraries that handle conditional rendering at the tag level. They added control components to enable conditional rendering without JS:

<Choose> <When condition={isLoading}> <div><p>Loading... </p></div> </When> <Otherwise> <div>{list.map(item => <Item item={item} />)}</div> </Otherwise> </Choose>Copy the code

Many people consider React(including JSX) to be their library of choice because they can handle rendering using pure HTML and JS in JSX.

I hope this React tutorial helped you learn about conditional rendering. If you like it, please share it with your friends. Finally, I’ve prepared a fully conditional rendering cheat sheet for you:

  • if
    • The most basic conditions render
    • Used to return early in a render (guard mode)
    • Cannot be used in return statements and JSX (except for self-calling functions)
  • if-else
    • Rarely use it because it’s too verbose
    • You can use the ternary or logical && operators instead
    • Cannot be used in return statements and JSX (except for self-calling functions)
  • Ternary operator
    • Use it instead of an if-else statement
    • It can be used in JSX and return statements
  • The logical && operator
    • Used when one end of the ternary operation returns NULL
    • It can be used in JSX and return statements
  • switch case
    • Avoid this as it is too verbose
    • You can use enumerations instead
    • Cannot be used in return statements and JSX (except for self-calling functions)
  • The enumeration
    • Use it for conditional rendering based on multiple states
    • Mapping multiple conditions perfectly
  • Nested conditional rendering
    • Avoid them for readability
    • You can split components, use if statements, or use hoc instead
  • HOCs (Advanced Components)
    • Components can focus on their primary purpose
    • Use HOC to shield conditional rendering
    • Use multiple composable hoc to shield multiple conditional renders
  • External template component
    • Avoid them and get used to JSX and JS