Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

apply multiple filters react

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>
    )
  }
}
like image 465
tom harrison Avatar asked Jul 20 '17 13:07

tom harrison


People also ask

How do you add multiple filters in HTML?

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.

How do you filter an array of objects in react?

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.

How do you filter data in react?

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.


1 Answers

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:

  • Using a boolean instead of a string in your case is more adapted. (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.
  • I would rename 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

like image 120
Cyril F Avatar answered Oct 19 '22 06:10

Cyril F