简体   繁体   中英

Double conditional rendering in react?

I'm building a small clothing store app in React, just to learn things. I implemented a filter by price section but I would want to be able to write a condition for the case in which there's no item in the selected price range, instead of the page being blank.

render() {
        const filteredOpt2 = this.state.items.filter(item => item.price <= 60);
        const filteredOpt3 = this.state.items.filter(item => item.price >= 60 && item.price <= 100);
        
        return (
              <div>
                    {
                         this.state.selectedOption === "option1"
                         ? <ProductList products={this.state.items} style={{marginLeft: 0}}/>
                         : this.state.selectedOption === "option2"
                         ? <ProductList products={filteredOpt2} style={{marginLeft: 0}}/>
                         : this.state.selectedOption === "option3"
                         ? <ProductList products={filteredOpt3} style={{marginLeft: 0}}/>
                         : null
                    }
              </div>
        )
}

I know the code is very repetitive and really not ideal, but I couldn't come up with a better approach for now.

So what I wish to do, is, let's say the filteredOpt2 results in an empty array, how and where could I implement a condition that says if this happens, display ap tag showing a text?

If not diving deep in the idea of component split you can just add condition in the template like this

const filteredOpt2 = this.state.items.filter((item) => item.price <= 60);
  const filteredOpt3 = this.state.items.filter(
    (item) => item.price >= 60 && item.price <= 100
  );

  return (
    <div>
      {this.state.selectedOption === "option1" ? (
        <ProductList products={this.state.items} style={{ marginLeft: 0 }} />
      ) : this.state.selectedOption === "option2" ? (
        <>
          {filteredOpt2.length > 0 ? (
            <ProductList products={filteredOpt2} style={{ marginLeft: 0 }} />
          ) : (
            <p>No items lower than 60</p>
          )}
        </>
      ) : this.state.selectedOption === "option3" ? (
        <>
          {filteredOpt3.length > 0 ? (
            <ProductList products={filteredOpt3} style={{ marginLeft: 0 }} />
          ) : (
            <p>No items between 60 and 100</p>
          )}
        </>
      ) : null}
    </div>

You are sending the product list down to ProductList component via props. In that component, where you use your props.products , you can add something like this:

{!props.products.length
  ? <p>No product matched the criteria</p> 
  : props.products.map(product => {... whatever your code is })
}

To elaborate, if the products.length is zero, you show your 'no product' text, otherwise, show the products.

You can do the filtering in advance, eg in a function and then render the list accordingly:

const filterItems = (items, filter) => {
    if (filter === "option1") return items;
    if (filter === "option2") return items.filter(item => item.price <= 60);
    if (filter === "option3") return items.filter(item => item.price >= 60 && item.price <= 100);
};
render() {
    const filtered = filterItems(this.state.items, this.state.selectedOption);
        
    return (
        <div>
            {filtered.length === 0 ? (
                <p>No products</p>
            ) : (
                <ProductList products={filtered} style={{marginLeft: 0}}/>
            )}
        </div>
    );
}

or even better let the ProductList component handle that:

render() {        
    return (
        <div>
            <ProductList 
                products={filterItems(this.state.items, this.state.selectedOption)} 
                style={{marginLeft: 0}}
            />
        </div>
    );
}
const ProductList = ({products}) => {
    if (products.length === 0) return <p>No products</p>;

    return ...
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM