0

In the following component, the handleDropdownChange function does not set the state for "data" on the first change, it only sets it after the second change. For example, when I select 'Electronics', nothing happens. I then select 'Produce', and the page loads all 'Electronics' products.

export default class ProductList extends Component {
        
    constructor(props){             
        super(props);       
        this.handleDropdownChange= this.handleDropdownChange.bind(this);
        this.state = {      
             data: fulldata
            };      
    }


    handleDropdownChange(e){
        
        e.preventDefault();
        var filtered_data = fulldata.filter(prod => prod.category == e.target.value);       
        this.setState({ data:filtered_data })
        
    }
    

   render(){

    return(
               <div>Category</div>
                        <select id="filter-cat" onChange={this.handleDropdownChange}>
                            <option value="Apparel">Apparel</option>    
                            <option value="Electronics">Electronics</option>
                            <option value="Produce">Produce</option>
                        </select>

              {this.state.data}
     );
    }
}
sotn
  • 1,833
  • 5
  • 35
  • 65

2 Answers2

0

Your code looks okay, although I'm not entirely sure how you're rendering this.state.data because by the looks of it it is an array. You can modify your handleDropdownChange to store the selected item instead.

Your state:

    this.state = {
      data: fulldata[0]
    };

Your onChange handler:

handleDropdownChange(e) {
  const filtered_data = fulldata.find(
    (prod) => prod.category === e.target.value
  );
  this.setState({ data: filtered_data });
}

Here's the working codesandbox example

  • Your code does work in the sandbox but it does not work in my code. I found a solution that I have provided as an answer. – sotn Dec 19 '20 at 08:56
0

The only thing that worked for me was found here:

setState doesn't update the state immediately

My updated method looks like this:

async handleDropdownChange(e){
        
        e.preventDefault();
        var filtered_data = fulldata.filter(prod => prod.category == e.target.value);       
        await this.setState({ data:filtered_data })
        
    }

This feels hacky and I wish there was a better way, but for now this is only solution that works me.

sotn
  • 1,833
  • 5
  • 35
  • 65