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>    );  }}