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 RenderingWe 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
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:
<h1> Big Time Shopping </h1>;{ this.state.isHiring ? ( <h2>Yes, we are hiring </h2> ) : ( <h2>Sorry, try again tomorrow</h2> );}
#
Extra, if there is timeLet's add a click event that toggles the value of our hiring.
We'll write a function
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)
<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:
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> ); }}