@JekaHC

Как создать фильтр для продуктов?

Есть компоненты:

Main.jsx
import React from "react";
import { Products } from "../Products";
import { Filter } from "../Filter";
import { Product } from "../Product";

class Main extends React.Component {
  state = {
    products: [],
  };

  componentDidMount() {
    fetch("./products.json")
      .then((responce) => responce.json())
      .then((data) => this.setState({ products: Object.values(data) }));
  }

  productFilter = (type = "all") => {
    const selected = [];
    return this.state.products.map((product) => {
      if (product.prod_status.contains(type)) {
        selected.push(product);
      }
    });
  };

  render() {
    const { products } = this.state;

    return (
      <main className="container content">
        <Filter />
        <Products products={products} />
      </main>
    );
  }
}

export { Main };

Filter.jsx
import React from "react";

class Filter extends React.Component {
  state = {
    type: "all",
  };

  hadleFilter = (event) => {
    this.setState({ type: event.target.dataset.type }, () => {
      this.props.productFilter(this.state.type);
    });
  };

  render() {
    return (
      <div clasName="row">
        <div className="sort_container">
          <h3 className="sort_title">Sortować według:</h3>
          <label>
            <input
              className="with-gap"
              name="prod-status"
              type="radio"
              data-type="all"
              onChange={this.hadleFilter}
              checked={this.state.type === "all"}
            />
            <span>All</span>
          </label>
          <label>
            <input
              className="with-gap"
              name="prod-status"
              type="radio"
              data-type="recommended"
              onChange={this.hadleFilter}
              checked={this.state.type === "recommended"}
            />
            <span>Recommended</span>
          </label>
          <label>
            <input
              className="with-gap"
              name="prod-status"
              type="radio"
              data-type="saleout"
              onChange={this.hadleFilter}
              checked={this.state.type === "saleout"}
            />
            <span>Saleout</span>
          </label>
          <label>
            <input
              className="with-gap"
              name="prod-status"
              type="radio"
              data-type="bestseller"
              onChange={this.hadleFilter}
              checked={this.state.type === "bestseller"}
            />
            <span>Bestseller</span>
          </label>
          <label>
            <input
              className="with-gap"
              name="prod-status"
              type="radio"
              data-type="promotion"
              onChange={this.hadleFilter}
              checked={this.state.type === "promotion"}
            />
            <span>Rromotion</span>
          </label>
          <label>
            <input
              className="with-gap"
              name="prod-status"
              type="radio"
              data-type="new"
              onChange={this.hadleFilter}
              checked={this.state.type === "new"}
            />
            <span>New</span>
          </label>
        </div>
      </div>
    );
  }
}

export { Filter };

Ссылка на весь репозиторий тут.

Вопрос- попытался сделать функцию productFilter() в Main.jsx, которую передаю в Filter.jsx для реализации фильтра после нажатия на любой radio. Ясное дело, что функция написана не правильно, прошу помочь исправить ошибки и довести фильтр в рабочее состояние.
  • Вопрос задан
  • 276 просмотров
Решения вопроса 1
0xD34F
@0xD34F Куратор тега React
Кроме полных данных храните также и отфильтрованные. Их и отображайте. Значение фильтра пусть хранится в родителе - передавайте его в экземпляр компонента фильтра вместе с функцией, которая его (значение) будет обновлять. При обновлении значения фильтра обновляете массив отфильтрованных данных.

const Filter = ({ title, values, value, onChange }) => (
  <div>
    <h3>{title}</h3>
    {values.map(n => (
      <label>
        <input
          type="radio"
          onChange={() => onChange(n)}
          checked={value === n}
        />
        {n}
      </label>
    ))}
  </div>
);

state = {
  ...
  filteredProducts: [],
  status: 'all',
}

onFilterStatusChange = status => {
  this.setState({ status });
}

filterProducts() {
  this.setState(({ status }) => ({
    filteredProducts: status === 'all'
      ? this.state.products
      : this.state.products.filter(n => n.prod_status.includes(status)),
  }));
}

componentDidUpdate(prevProps, prevState) {
  if (this.state.status !== prevState.status) {
    this.filterProducts();
  }
}

render() {
  ...
    <Filter
      title="Status:"
      values={[ 'all', 'recommended', 'saleout', 'bestseller', 'new' ]}
      value={this.state.status}
      onChange={this.onFilterStatusChange}
    />
    <Products products={this.state.filteredProducts} />
  ...
}
Ответ написан
Пригласить эксперта
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы