I have 2 buttons which when clicked should filter by novelty
or offer
, I am able to make it so that when novelty is clicked it will filter by this but I am unable to make it so that if both are click it will filter by both novelty
and offer
How can I make it so that when both novelty and offer are clicked it will filter by both of these?
https://www.webpackbin.com/bins/-KpVGNEN7ZuKAFODxuER
import React from 'react'
export default class extends React.Component {
constructor() {
super()
this.state = {
products: [
{ id: 1, novelty: true, offer: false, name: 'test1' },
{ id: 2, novelty: true, offer: true, name: 'test2' },
{ id: 3, novelty: false, offer: true, name: 'test3' }
],
display: 'all',
filters: [
{novelty:'true'},
{offer: 'true'}
]
}
}
setCategory (category) {
this.setState({
display: category
});
}
render() {
return(
<div>
<button onClick={()=>this.setCategory(true)}>Akce</button>
<button onClick={()=>this.setCategory(true)}>Offer</button>
{
this.state.products.filter( product =>
products.offer === this.state.display ||
this.state.display==='all')
.map(product =>
<div>{product.name}</div>
)
}
</div>
)
}
}
addFilter(ffAH, true); The first argument to addFilter is the filter function you want to add, the 2nd argument is optional, if true, it tells the data set to apply all filters after the filter is added. If false or undefined, it simply adds the filter function to its internal list and does nothing else.
To filter an array of objects in React:Call the filter() method on the array. On each iteration, check if a certain condition is met. The Array. filter methods returns an array with all elements that satisfy the condition.
Data filtering. The most common way to filter data in JavaScript is to use the array's filter() method. It can be used on any array and, provided a filtering function, returns a new array containing only selected items.
Here is the final version I've come up with:
import React from 'react'
export default class extends React.Component {
constructor() {
super()
this.state = {
products: [
{ id: 1, novelty: true, offer: false, name: 'test1' },
{ id: 2, novelty: true, offer: true, name: 'test2' },
{ id: 3, novelty: false, offer: true, name: 'test3' }
],
filters: {
novelty: true,
offer: true
}
}
}
setCategory (category) {
this.setState((state) => ({
filters: Object.assign({}, state.filters, { [category]: !state.filters[category] })
}));
}
render() {
console.log(this.state.filters)
return(
<div>
<button onClick={()=>this.setCategory('novelty')}>Akce</button>
<button onClick={()=>this.setCategory('offer')}>Offer</button>
{ this.state.products
.filter(product => product.novelty === this.state.filters.novelty || product.offer === this.state.filters.offer)
.map(product =>
<div key={product.id}>{product.name}</div>
)}
</div>
)
}
}
https://www.webpackbin.com/bins/-KpVHqfkjeraq6pGvHij
A few things:
true
instead of 'true'
).display: 'all'
isn't required for your use case. You can compute this value from your filters if you need to.setCategory
receive which category
you want to set as a param.setCategory
to setFilter
Also, I'm using the asycnhronous version of setState
. This allows you to hand in a function.
this.setState((state) => ({
filters: Object.assign({}, state.filters, { [category]: !state.filters[category] })
}));
Here I'm using Object.assign
to create a new Object. I populate him with state.filters
and finally I update the filter you want to.
category
will either be novelty
or offer
and thanks to that I'm using the shorthand version of [category]
.
To conclude, I also update your filter
function to check the product.novelty
against the filter.novelty
or the product.offer
with the filter.offer
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With