Двойной условный рендеринг в React? - PullRequest
0 голосов
/ 13 июля 2020

Я создаю небольшое приложение для магазина одежды на React, просто чтобы научиться чему-то. Я реализовал фильтр по ценовому разделу, но я хотел бы иметь возможность написать условие для случая, когда в выбранном ценовом диапазоне нет товара, вместо того, чтобы страница была пустой.

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

Я знаю код очень повторяющийся и действительно не идеальный, но я не мог пока придумать лучшего подхода.

Итак, что я sh должен сделать, это, скажем, filterOpt2 приводит к пустому массив, как и где я могу реализовать условие, которое говорит, что если это произойдет, отобразить тег ap с текстом?

Ответы [ 3 ]

1 голос
/ 13 июля 2020

Вы отправляете список продуктов до ProductList компонента через props. В этом компоненте, где вы используете свой props.products, вы можете добавить что-то вроде этого:

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

Чтобы уточнить, если products.length равен нулю, вы показываете свой текст «нет продукта», в противном случае, показать товары.

1 голос
/ 13 июля 2020

Вы можете выполнить фильтрацию заранее, например, в функции, а затем соответствующим образом отобразить список:

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

или, что еще лучше, позволить компоненту ProductList обработать это:

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 ...
};
1 голос
/ 13 июля 2020

Если не углубляться в идею разделения компонентов, вы можете просто добавить условие в шаблон, как это

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>
...