Author avatar

Adam Garrett-Harris

How to Show Components Conditionally in React

Adam Garrett-Harris

  • Aug 2, 2019
  • 5 Min read
  • 107 Views
  • Aug 2, 2019
  • 5 Min read
  • 107 Views
Web Development
React

Introduction

When it comes to conditional rendering with React, you have a lot of options. Some might feel more intuitive than others, but don't dismiss the ones that are harder to understand. They can be a lot more succinct, and they get easier to understand once you get used to it. And even if you decide not to write your code that way, you will come across the last two options (using && and ternaries) in code often, so it's good to be familiar with them.

Option 1 - If Component

Let's say that you have a Home component and, depending on if the user has posts or not, you want to either show the Posts component or the NoPosts component.

If you're familiar with Angular, and the ng-if directive, you might be tempted to write an If component like this:

1
2
3
4
5
const If = ({ condition, children }) => {
  if (condition) {
    return children;
  }
};
js

This will render the children of the component, only if the condition is met. You would use it like this:

1
2
3
4
5
6
7
const Home = ({ posts }) => {
  return (
    <If condition={posts}>
      <Posts posts={posts} />
    </If>
  );
};
js

And, while you certainly can do this in React, there are other ways of rendering conditionally that are more succinct.

Option 2 - IIFE

Or you might want to write an if statement inside of your SJX like this:

1
2
3
4
5
6
7
8
9
10
11
const Home = ({ posts }) => {
  return (
    <div>
      {if (posts) {
        <Posts posts={posts} />
      } else {
        <NoPosts />
      }}
    </div>
  )
}
js

But this doesn't work because an if statement isn't an expression. To make it an expression, you could use an immediately-invoked function expression (IIFE).

1
2
3
4
5
6
7
8
9
10
11
12
13
const Home = ({ posts }) => {
  return (
    <div>
      {(() => {
        if (posts) {
          return <Posts posts={posts} />;
        } else {
          return <NoPosts />;
        }
      })()}
    </div>
  );
};
js

Option 3 - Variable

You could also use a variable that you conditionally set with different JSX values:

1
2
3
4
5
const Home = ({ posts }) => {
  const postsSection = posts ? <Posts posts={posts} /> : <NoPosts />;

  return <div>{postsSection}</div>;
};
js

Option 4 - Render Function

You could extract that variable out into a function as well.

1
2
3
const renderPosts = posts => (posts ? <Posts posts={posts} /> : <NoPosts />);

const Home = ({ posts }) => <div>{renderPosts(posts)}</div>;
js

I'm not a huge fan of writing render functions in React because it's so close to being a component.

Option 5 - Component

Instead of a render function, you can make it a small component that renders Posts or NoPosts.

1
2
3
4
5
6
7
const Posts = ({ posts }) => (posts ? <Posts posts={posts} /> : <NoPosts />);

const Home = ({ posts }) => (
  <div>
    <Posts posts={posts} />
  </div>
);
js

Option 6 - Ternary

And if your logic is simple enough, you could use a ternary inside of your JSX.

1
2
3
const Home = ({ posts }) => (
  <div>{posts ? <Posts posts={posts} /> : <NoPosts />}</div>
);
js

And you can also nest ternaries, if you want.

1
2
3
4
5
6
7
8
9
10
11
const Home = ({ posts }) => (
  <div>
    {posts ? (
      <Posts posts={posts} />
    ) : firstLogin ? (
      <Onboarding />
    ) : (
      <NoPosts />
    )}
  </div>
);
js

Option 7 - The And Operator

If your logic is as simple as showing a component or showing nothing, you can return a null in your ternary:

1
2
3
{
  posts ? <Posts posts={posts} /> : null;
}
js

And an even more terse way of doing that is with the "and" operator (&&).

1
2
3
{
  posts.length > 0 && <Posts posts={posts} />;
}
js

This works because, in React, null and false don't render anything and the && operator returns the first falsy value or the second value. So, if posts.length is greater than 0, then it will render the Posts component; otherwise, it will render nothing.

What if the Component Needs to Hide Itself?

All of these examples are about whether or not to render a component, but you might actually want the component to take care of the logic of whether or not to render itself. You can do that. The component can conditionally return some JSX or null, like this:

1
2
3
4
5
6
7
8
9
10
11
12
13
const Posts = ({ isDistractionFreeMode, posts }) => {
  if (isDistractionFreeMode) {
    return null;
  }

  return (
    <div>
      {posts.map(p => (
        <div>{p.excerpt}</div>
      ))}
    </div>
  );
};
js

Conclusion

There are many ways to conditionally render components, or plain JSX, in React because there are many ways to do things conditionally in JavaScript. You can even use switch statements. Which one you use comes down to preference and the particular use case. And, if you pick one and decide to change later, you can always refactor from one form to another.

For more examples, check out these articles from the React documentation:

0