Three ways to conditionally render components with React and JSX

Sometimes, you want to render a UI component only if a certain condition is true. Perhaps a feature is enabled for a subset of users only (such as administrators or premium accounts), or maybe part of the UI can be toggled on and off in the app’s settings. I’d like to share a few different ways to conditionally render a component with React and JSX that I’ve found useful. Which one you should choose depends on the situation. Sometimes, one approach may be the best tool for the job. Other times, it may come down to personal preference.

Getting started

Let’s consider a basic web app layout. We have a main content section and a sidebar. There’s also a special toolbar that only administrators should be able to see. This toolbar should be hidden from regular users.

For our code examples, we’ll be inside the render() method of the parent component of these three sections. Here’s what it might look like without any conditional rendering:

render()
{
    return (
        <AdminToolbar/>
        <PrimaryContent/>
        <Sidebar/>
    );
}

Let’s assume that this parent component has a prop named isAdmin that we’ll use to figure out if AdminToolbar should render or not.

Now that we’ve established our context, let’s look at our various options for conditional rendering.

Approach 1: A variable and an if() statement

The most basic approach is to store an instance of our AdminToolbar component in a variable, but only if the isAdmin prop is true.

let adminBar = null;
if(this.props.isAdmin)
{
    adminBar = <AdminToolbar/>;
}

Then, we’ll use our ability to embed expressions in JSX to reference the variable inside our JSX.

return (
    { adminBar }
    <PrimaryContent/>
    <Sidebar/>
);

React has no problem dealing with a null value in JSX. If the adminBar variable is null, React will skip over it without rendering anything.

Approach 2: Return null from component’s render() method

In the next example, we leave it up to the AdminToolbar component to decide on its own whether to render or not. Let’s give AdminToolbar its own isAdmin prop so that we can pass our value down one more level:

render()
{
    return (
        <AdminToolbar isAdmin={this.props.isAdmin}/>
        <PrimaryContent/>
        <Sidebar/>
    );
}

Then, in the render() method of the AdminToolbar component, we’ll return null if the prop is false.

class AdminToolbar extends React.Component
{
    render()
    {
        if(!this.props.isAdmin)
        {
            return null;
        }
        return (
            <div>
                { /* omitted for simplicity */ }
            </div>
        );
    }
}

Similar to the previous example, React understands that it shouldn’t render anything when a component returns null from its render() method.

Approach 3: Ternary operator (a ? b : c)

As a final option, we can take advantage of the shorthand nature of the ternary operator to embed everything directly inside our JSX:

render()
{
    return (
        <div>
            { this.props.isAdmin ? <AdminToolbar/> : null }
            <PrimaryContent/>
            <Sidebar/>
        </div>
    );
}

In my opinion, this approach works best when we don’t have any props to pass to the component (or a very small number of props) because we can keep everything on one line. Usually, if we need to pass many props to a component, it’s better to place the props on multiple lines. A ternary operator gets more difficult to read in that situation, and I don’t think it’s particularly obvious how to format this type of complex expression over multiple lines.

This following example seems somewhat reasonable, I guess:

render()
{
    return (
        <div>
            {
                this.props.isAdmin ?
                (
                    <AdminToolbar
                        name="Administrator"
                        needsUpdate={true}/>
                )
                : null
            }
            <PrimaryContent/>
            <Sidebar/>
        </div>
    );
}

However, I don’t think I’d be happy with this formatting if the condition were longer — with multiple parts separated by && and || operators. Similarly, if the final expression were more complex than null, I feel like the mental overhead to understand how each expression fits into the ternary operator would become too high. In my opinion, if the ternary operator needs to be split into multiple lines, our first approach (with the variable and an if() statement) is a much better choice. For one-liners, though, the ternary operator is a pretty compelling option.

One, two, or three?

Which approach do you prefer? Do you know about any other ways to conditionally render a component in React and JSX? If I forgot to include anything, let me know in the comments!

About Josh Tynjala

Josh Tynjala is a front end developer, open source contributor, karaoke enthusiast, and he likes bowler hats. You might be familiar with his project, Feathers UI, an open source user interface library for Starling Framework. You should follow Josh on Twitter.

Discussion

    1. Josh Tynjala

      That’s interesting. I would have expected the result of the && operator to always return true or false. I guess I don’t know my ECMAScript spec well enough. So I suppose this means that the && operator simply returns one of the values on either side (without coercion to boolean!). If the left-hand side is falsy, it returns that. Otherwise, it returns the right-hand side, whatever value it may happen to hold. The JS runtime doesn’t even need to figure out if the right-hand side is truthy or falsy, unless it’s inside an if() statement or something.

      While I can figure out why this approach with the && operator works, that feels like a lot of mental work. The code ends up being pretty short, compared to the other approaches, but I’d say that it’s not really intuitive, unless you’re an expert. I’m not sure that I like that one. The ternary operator is slightly longer, but more clear, in my opinion. (Though, I’ll admit that when I was a beginner, I always had to pause and think for a moment to remember how the ternary operator worked… so that one isn’t necessarily the most intuitive either).

Leave a Reply

Your email address will not be published. Required fields are marked *