We can create multiple components in React and render only few of them and not others which could be controlled through state variables. Conditional rendering sounds very heavy, but it can be done using simple javascript if statements or conditional operators.
Consider these two components
function TenantGreeting(props) {
return <h1>Welcome back!</h1>;
}
function VisitorGreeting(props) {
return <h1>Please fill in your details.</h1>;
}
We’ll create a Hello component that displays either of these components depending on whether a user is checked in:
function Hello(props) {
const isCheckedIn= props.isCheckedIn;
if (isCheckedIn) {
return <TenantGreeting/>;
}
return <VisitorGreeting/>;
}
ReactDOM.render(
// Try changing to isCheckedIn={true}:
<Hello isCheckedIn={false} />,
document.getElementById('root')
);
See this live in action here.
https://codepen.io/anilpank/pen/yLBZQwR
How to use stateful components to do conditional rendering
Consider these two new components representing ComeIn and GetOut buttons:
function ComeInButton(props) {
return (
<button onClick={props.onClick}>
Come In
</button>
);
}
function GetOutButton(props) {
return (
<button onClick={props.onClick}>
Get Out
</button>
);
}
Let’s create a stateful component called HomeControl. In this example, In the example, we will create a stateful component called HomeControl. It will render either or depending on its current state.
class HomeControl extends React.Component {
constructor(props) {
super(props);
this.handleComeInClick = this.handleComeInClick.bind(this);
this.handleGetOutClick = this.handleGetOutClick.bind(this);
this.state = {isInside: false};
}
handleComeInClick() {
this.setState({isInside: true});
}
handleGetOutClick() {
this.setState({isInside: false});
}
render() {
const isInside = this.state.isInside ;
let button;
if (isInside ) {
button = <GetOutButton onClick={this.handleGetOutClick} />;
} else {
button = <ComeInButton onClick={this.handleComeInClick} />;
}
return (
<div>
<Hello isCheckedIn={isInside} />
{button}
</div>
);
}
}
ReactDOM.render(
<HomeControl/>,
document.getElementById('root')
);
You can see it live in action here. https://codepen.io/anilpank/pen/BaBMvOq
We can also use inline if with && operator to make conditional rendering more succinct. This is very useful where you want to conditionally include a statement based on some state or prop value.
function AlertSystem(props) {
const unreadMessages = props.alerts;
return (
<div>
<h1>Hello!</h1>
{unreadMessages.length > 0 &&
<h2>
You have {unreadMessages.length} unread alerts.
</h2>
}
</div>
);
}
const messages = ['Great', 'Greater', 'Greater'];
ReactDOM.render(
<AlertSystem alerts={messages} />,
document.getElementById('root')
);
You can see it live here. https://codepen.io/anilpank/pen/eYOxxzB
Completely avoid a component from rendering
There could be some use cases where you want to completely avoid a component from rendering based on some condition. The trick for this is pretty simple, you basically return null instead of usual output in render method. Below is an example.
function ErrorToast(props) {
if (!props.error) {
return null;
}
return (
<div className="warning">
Oops, You got an error!
</div>
);
}
class Screen extends React.Component {
constructor(props) {
super(props);
this.state = {showError: true};
this.handleToggleClick = this.handleToggleClick.bind(this);
}
handleToggleClick() {
this.setState(state => ({
showError: !state.showError
}));
}
render() {
return (
<div>
<ErrorBanner error={this.state.showError} />
<button onClick={this.handleToggleClick}>
{this.state.showError? 'Hide' : 'Show'}
</button>
</div>
);
}
}
ReactDOM.render(
<Screen />,
document.getElementById('root')
);
You can see it live here. https://codepen.io/anilpank/pen/wvwNNPv
Note that all component life cycle methods (like componentDidUpdate) will still be called as usual and returning null from a component render won’t change this behavior.