Answer the question
In order to leave comments, you need to log in
How to create a product filter in React?
There are React
Main.jsx components
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 };
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 };
Answer the question
In order to leave comments, you need to log in
In addition to the full data, store the filtered ones as well. Display them. Let the filter value be stored in the parent - pass it to the filter component instance along with the function that will update it (the value). When you update the filter value, you update the array of filtered data.
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} />
...
}
return this.state.products.map((product) => {
try forEach
insteadmap
productFilter = (type = "all") => {
const selected = [];
return this.state.products.map((product) => {
if (product.prod_status.contains(type)) {
selected.push(product);
}
});
};
productFilter = function (t = "all") {
return this.state.products.filter((p) => p.prod_status.contains(t));
};
Didn't find what you were looking for?
Ask your questionAsk a Question
731 491 924 answers to any question