Skip to main content

Intro to Conditional Rendering in React

Learning Objectives

  • Be able to describe why conditional rendering is important
  • Use a ternary operator for conditional rendering

Conditional Rendering

We may want to render different things depending on state. For example, if a product is out of stock, we may want to hide the 'add to cart' button and instead put a message that says 'sorry out of stock'.

Since our dataset is simple and we don't have stock of items, what we can do is just put a simple message that states whether or not we are hiring. Let's add to our constructor isHiring and set it to true

App.js
constructor(props) {
super(props);
this.state = {
products: products,
name: "",
price: 0,
description: "",
isHiring: true,
};
this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
}

We'll use a ternary operator, which is just shorthand for an if/else statement

The following two examples are equivalent

const fact1 = true;
const fact2 = false;
let print;

if (fact1) {
print = "yes, it is true";
} else {
print = "no, that is false";
}

console.log(print);
let print = fact2 ? "yes, it is true" : "no, that is false";

console.log(print);

Now we can use this syntax to conditionally render the text of an h2 element:

App.js
<h1> Big Time Shopping </h1>;
{
this.state.isHiring ? (
<h2>Yes, we are hiring </h2>
) : (
<h2>Sorry, try again tomorrow</h2>
);
}

Extra, if there is time

Let's add a click event that toggles the value of our hiring.

We'll write a function

App.js
toggleHiring() {
this.setState({ isHiring: !this.state.isHiring });
}

and bind the value of this in the constructor

Finally, let's add a click event to our h1 (we could have made a button or chosen another element as well)

App.js
<h1 onClick={this.toggleHiring}> Big Time Shopping </h1>;
{
this.state.isHiring ? (
<h2>Yes, we are hiring </h2>
) : (
<h2>Sorry, try again tomorrow</h2>
);
}

More ways to conditionally render - caveat React updates often always check the date of articles - if something isn't working as expected, it may be that React was updated - these all should work with React 16.x

The full code for today's build:

App.js
class App extends React.Component {
constructor() {
super();
this.state = {
products: products,
name: "",
price: 0,
description: "",
isHiring: true,
};

this.handleChange = this.handleChange.bind(this);
this.handleSubmit = this.handleSubmit.bind(this);
this.toggleHiring = this.toggleHiring.bind(this);
}

handleChange(event) {
// this.state.value = event.target.value // NO!!!
this.setState({ [event.target.id]: event.target.value });
}

handleSubmit(event) {
event.preventDefault();
const newItem = {
name: this.state.name,
price: this.state.price,
description: this.state.description,
};
this.setState({
products: [...this.state.products, newItem],
name: "",
price: 0,
description: "",
});
}

toggleHiring() {
this.setState({ isHiring: !this.state.isHiring });
}

render() {
return (
<div>
<h1 onClick={this.toggleHiring}> Big Time Shopping </h1>
{this.state.isHiring ? (
<h2>Yes, we're hiring!</h2>
) : (
<h3>Sorry, try again tomorrow </h3>
)}
<form onSubmit={this.handleSubmit}>
<label htmlFor="name">Name</label>
<input
type="text"
value={this.state.name}
onChange={this.handleChange}
id="name"
/>
<br />
<label htmlFor="price">Price</label>
<input
type="number"
value={this.state.price}
onChange={this.handleChange}
id="price"
/>
<br />
<label htmlFor="description">Description</label>
<input
type="textarea"
value={this.state.description}
onChange={this.handleChange}
id="description"
/>
<br />
<input type="submit" />
</form>
<div>
<h2>Preview our new item</h2>
<h3>Name: {this.state.name}</h3>
<h4>Price: {this.state.price}</h4>
<h5>Description: {this.state.description}</h5>
</div>
<ul>
{this.state.products.map((product) => {
return (
<li>
{product.name} | {product.price} | {product.description}
</li>
);
})}
</ul>
</div>
);
}
}