Conditional Rendering
# 06. Conditional Rendering
Conditional rendering in React works the same way conditions work in JavaScript. Use JavaScript operators like if (opens new window) or the conditional operator (opens new window) to create elements representing the current state, and let React update the UI to match them.
Consider these two components:
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
2
3
4
5
6
7
Then create a Greeting component that displays either of these components depending on whether a user is logged in:
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
// Conditionally render a component (UI)
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
ReactDOM.render(
// Try changing to isLoggedIn={true}:
<Greeting isLoggedIn={false} />,
document.getElementById('root')
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# Element Variables
You can use variables to store elements. This can help you conditionally render a part of the component while the rest of the output doesn't change.
class LoginControl extends React.Component {
constructor(props) {
super(props);
this.handleLoginClick = this.handleLoginClick.bind(this);
this.handleLogoutClick = this.handleLogoutClick.bind(this);
this.state = {isLoggedIn: false};
}
handleLoginClick() {
this.setState({isLoggedIn: true});
}
handleLogoutClick() {
this.setState({isLoggedIn: false});
}
render() {
const isLoggedIn = this.state.isLoggedIn;
let button;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
ReactDOM.render(
<LoginControl />,
document.getElementById('root')
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
Try it on CodePen (opens new window)
This approach is somewhat complex.
# Inline If with Logical && Operator
You can embed expressions in JSX (opens new window) by wrapping them in curly braces. This includes the JavaScript logical && operator. It can be handy for conditionally including an element:
function Mailbox(props){
const unreadMeg = props.unreadMeg
return (
<div>
{
unreadMeg.length &&
<h2>You have {unreadMeg.length} unread messages</h2>
}
</div>
)
}
const meg = ['1','22','33']
ReactDOM.render(
<Mailbox unreadMeg={meg} />,
document.getElementById('root')
)
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
If the condition is true, the element right after && will appear in the output. If it is false, React will ignore and skip it.
Note that returning a falsy expression will still cause the element after && to be skipped but will return the falsy expression. In the example below, <div>0</div> will be returned by the render method.
render() {
const count = 0;
return (
<div>
// This will render count's value
{ count && <h1>Messages: {count}</h1>}
</div>
);
}
2
3
4
5
6
7
8
9
# Ternary Operator
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
2
3
4
5
6
7
8
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn
? <LogoutButton onClick={this.handleLogoutClick} />
: <LoginButton onClick={this.handleLoginClick} />
}
</div>
);
}
2
3
4
5
6
7
8
9
10
11
You can use the ternary operator to conditionally render the appropriate component.
# Preventing Component from Rendering
Prevent rendering by having the render method return null:
function WarningBanner(props) {
if (!props.warn) {
// Returning null prevents the component from rendering
return null;
}
return (
<div className="warning">
Warning!
</div>
);
}
class Page extends React.Component {
constructor(props) {
super(props);
this.state = {showWarning: true};
this.handleToggleClick = this.handleToggleClick.bind(this);
}
handleToggleClick() {
this.setState(state => ({
showWarning: !state.showWarning
}));
}
render() {
return (
<div>
<WarningBanner warn={this.state.showWarning} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning ? 'Hide' : 'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Page />,
document.getElementById('root')
);
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
Returning null from a component's render method does not affect the firing of the component's lifecycle methods. For instance, componentDidUpdate will still be called.