In React, you can create different components to encapsulate the various behaviors you need. Then, you can render only a part of them based on changes in the application's state.
Conditional rendering in React is consistent with JavaScript. You use JavaScript operators like if or the conditional operator to create elements representing the current state, and then let React update the UI based on them.
Let's look at two components first:
function UserGreeting(props) {
return <h1>Welcome back!</h1>;
}
function GuestGreeting(props) {
return <h1>Please sign up.</h1>;
}
We will create a Greeting component that displays one of these two components depending on whether the user is logged in:
React Example
function Greeting(props) {
const isLoggedIn = props.isLoggedIn;
if (isLoggedIn) {
return <UserGreeting />;
}
return <GuestGreeting />;
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Greeting isLoggedIn={false} />);
Element Variables
You can use variables to store elements. This can help you conditionally render a part of a component while the other output parts do not change.
In the following example, we will create a stateful component called LoginControl.
It will render either <LoginButton /> or <LogoutButton /> based on its current state. It will also render a <Greeting /> from the previous example.
React Example
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 = null;
if (isLoggedIn) {
button = <LogoutButton onClick={this.handleLogoutClick} />;
} else {
button = <LoginButton onClick={this.handleLoginClick} />;
}
return (
<div>
<Greeting isLoggedIn={isLoggedIn} />
{button}
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<LoginControl />);
Inline if with Logical AND Operator &&
You can embed any expression in JSX by wrapping it in curly braces, including JavaScript's logical AND && operator. It can be used for conveniently conditionally rendering an element.
React Example
function Mailbox(props) {
const unreadMessages = props.unreadMessages;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread messages.
</h2>
}
</div>
);
}
const messages = ['React', 'Re: React', 'Re:Re: React'];
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Mailbox unreadMessages={messages} />);
In JavaScript, true && expression always evaluates to expression, and false && expression always evaluates to false.
Therefore, if the condition is true, the element right after && will be rendered. If it is false, React will ignore and skip it.
Inline If-Else with Conditional Operator
Another method for conditionally rendering elements is to use the JavaScript conditional operator:
condition ? true : false
In the following example, we use it to conditionally render a small block of text.
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
The user is <b>{isLoggedIn ? 'currently' : 'not'}</b> logged in.
</div>
);
}
It can also be used for larger expressions, although it is less obvious:
render() {
const isLoggedIn = this.state.isLoggedIn;
return (
<div>
{isLoggedIn ? (
<LogoutButton onClick={this.handleLogoutClick} />
) : (
<LoginButton onClick={this.handleLoginClick} />
)}
</div>
);
}
Preventing Component from Rendering
In rare cases, you might want a component to hide itself even though it was rendered by another component. To do this, return null instead of its render result.
In the following example, <WarningBanner /> is conditionally rendered based on the value of the warn prop. If the value of warn is false, the component does not render:
React Example
function WarningBanner(props) {
if (!props.warn) {
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(prevState => ({
showWarning: !prevState.showWarning
}));
}
render() {
return (
<div>
<WarningBanner warn={this.state.showWarning} />
<button onClick={this.handleToggleClick}>
{this.state.showWarning ? 'Hide' : 'Show'}
</button>
</div>
);
}
}
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(<Page />);
Returning null from a component's render method does not affect the firing of its lifecycle methods. For instance, componentWillUpdate and componentDidUpdate will still be called.
YouTip