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!