Navigate back to the homepage

Conditional Rendering In React

Dennis Morello
March 11th, 2019 · 2 min read

The declarative approach of React makes writing user interfaces easier than ever. In this post, I will explain how to conditionally render things by using the component composition pattern.

Conditional Rendering – The Classic Way

A common way to conditionally render something in React is by using inline if with logical && operator:

1const UserNotifications = props => (
2 <div>
3 <h2>Hi {props.userName}!</h2>
4 {props.unreadNotifications > 0 && (
5 <p>You have {props.unreadNotifications} notifications.</p>
6 )}
7 </div>
8);

If you have to render either A or B depending on a conditional statement, the ternary conditional operator is often used:

1const UserLogStatus = props => (
2 <div>
3 <h2>Welcome to morello.dev</h2>
4 {props.loggedIn ? (
5 <button onClick={props.onLogOutClicked}>Log Out</button>
6 ) : (
7 <button onClick={props.onLogInClicked}>Log In</button>
8 )}
9 </div>
10);

The techniques seen above are perfectly legal in React, but we can use component composition to make conditional rendering more elegant and easier to read.

Conditional Rendering Using Component Composition

We can use the component composition pattern to conditionally render parts of UI. Let’s see how!

For a refresh on component composition pattern in React, see this post by Robin Wieruch.

Conditional Components

Every if-then-else code block consists of two parts: the logical condition that has to be evaluated and the components to be conditionally rendered.

We can go further with this consideration by turning the if-then-else block into If, Then and Else components. We pass the condition as props to If, and we put Then and Else inside it. The Then component contains the stuff to render when the condition evaluates to true, and the Else component contains the stuff to render when the condition evaluates to false:

1const UserLogStatus = props => (
2 <If condition={props.loggedIn}>
3 <Then>
4 <button onClick={props.onLogOutClicked}>Log Out</button>
5 </Then>
6 <Else>
7 <button onClick={props.onLogInClicked}>Log In</button>
8 </Else>
9 </If>
10);

Everything sounds cool, but how could we implement the If, Then and Else components? Here is my solution, but feel free to submit yours in the comment area 💡

If, Then, Else

We start by considering the If component, as it is the parent. The idea is to take the condition passed as props, evaluate it and render the children of Then if the result is truthy, otherwise render the children of Else.

Note that, in order for this to work, If must be the parent of Then and Else. Violation of this constraint would make the code not working as expected.

If

Let’s see the code of the If component:

1const If = props => {
2 const thenComponent =
3 "length" in props.children
4 ? props.children.find(child => child.type.name === "Then")
5 : props.children.type.name === "Then"
6 ? props.children
7 : null;
8
9 const elseComponent =
10 "length" in props.children
11 ? props.children.find(child => child.type.name === "Else")
12 : props.children.type.name === "Else"
13 ? props.children
14 : null;
15
16 return props.condition ? thenComponent : elseComponent;
17};

The component logic is quite simple: we evaluate props.condition and return Then or Else depending on the result of the evaluation (see the return statement).

Let’s focus on the assignment of thenComponent (the same considerations hold for elseComponent):

1const thenComponent =
2 "length" in props.children
3 ? props.children.find(child => child.type.name === "Then")
4 : props.children.type.name === "Then"
5 ? props.children
6 : null;

We first check if props.children is an array or an object by testing the presence of length property:

  • if props.children is an array, we look for the child whose name is "Then", and we assign it to thenComponent
  • if props.children is not an array, we check if it is an instance of Then, and we assign it to thenComponent

If both tests fail, we assign null to thenComponent (so nothing will be rendered).

Then/Else

Implementation of Then and Else component is the same. Let’s see the code for the Then component as a representative example:

1const Then = props => props.children;

This super-tricky function returns its children. Easy enough.

Final Considerations

We can pass just Then to If when we want to render something only if the condition is truthy:

1<If condition={1 + 1 === 2}>
2 <Then>1 plus 1 equals 2</Then>
3</If>

This is equivalent to inline if with logical && operator, which is quicker to write but produces less readable code.

The same is valid for Else:

1<If condition={myCondition}>
2 <Else>myCondition is false</Else>
3</If>

In this case, we could just negate the condition and change Else with Then:

1<If condition={!myCondition}>
2 <Then>myCondition is false</Then>
3</If>

Live Demo

See the live demo on CodeSandbox.

More articles from Dennis Morello

React Awesome Reveal

Meet my new library for animating React components using Intersection Observer API and CSS Animations!

December 15th, 2019 · 2 min read

You Will Stop Using LocalStorage

Goodbye LocalStorage, welcome Key-Value Storage!

April 25th, 2019 · 2 min read
© 2019 Dennis Morello
Link to $https://twitter.com/dennismorelloLink to $https://github.com/dennismorelloLink to $https://instagram.com/dennismrlLink to $https://www.linkedin.com/in/dennismorello