3

I have a State with flights, and I have a slider to change the max price to change visibility of the flight elements.

maxpriceFilter() {

    var flightOffer = this.state.flightOffer;
    var sliderPrice = this.state.sliderPrice;

    for (var i = 0; i < flightOffer.length; i++) {
        if( flightOffer[i].price > sliderPrice) {   

            this.setState(
                {[flightOffer[i].hiddenprice] : true}
            );
        };
    }

This code is adding a undefined field with status true in the root of the state though.. I cant find any best practice on this, other then using computed fields. But I cant get the computed field working either..

Could someone please help me out here?

user3611459
  • 3,311
  • 6
  • 16
  • 18
  • Can you share how your state looks like? What I can see is that your state is an array so try using `this.setState({flightOffer[i].hiddenprice : true});` – iamsaksham Jun 06 '16 at 12:38
  • @iamsaksham that's actually a feature from ES6 where you define the keys dynamically in the defining object. https://babeljs.io/repl/#?evaluate=true&lineWrap=false&presets=es2015%2Creact%2Cstage-0&experimental=true&loose=false&spec=false&playground=false&code=var%20key%20%3D%20'test'%3B%0Avar%20value%20%3D%20true%3B%0A%0Aconst%20obj%20%3D%20%7B%0A%20%20%5Bkey%5D%3A%20value%0A%7D%3B – agmcleod Jun 06 '16 at 12:59

2 Answers2

23

You don't want to do a setState call in a loop, that will have the react component render multiple times. Build a new state object and call the setState once. You also don't want to filter it out by an if statement, but set previous values to hidden:

maxpriceFilter() {

    var flightOffer = this.state.flightOffer;
    var sliderPrice = this.state.sliderPrice;
    var newState = {};

    for (var i = 0; i < flightOffer.length; i++) {
        newState[flightOffer[i].hiddenprice] = flightOffer[i].price > sliderPrice;
    }

    this.setState(newState);

    // ...
}

If you're still having issues, it could be that the hiddenprice property isn't what you expect? Might need to post your render() function as well.

agmcleod
  • 13,321
  • 13
  • 57
  • 96
  • Not sure about state being called each time in the loop. Doesn't React merge all setState() calls at the end of the cycle to only call it once ? – Pierre Criulanscy Jun 06 '16 at 13:25
  • Ah you might be correct. Did a small jsfiddle using a count variable, and it just logged it once. Still, i think calling setState once would be less expensive, but that's getting into more optimization stuff instead of functional :) https://jsfiddle.net/69z2wepo/44677/ – agmcleod Jun 06 '16 at 14:21
1

Instead of doing your looping when you're updating the state, why not just do the switch on render?

You're probably already looping over all flightOffers in render(). So, just add the check there. Inside your render, pass hiddenPrice={offer.price > sliderPrice} as a prop, or use it directly where you control the visibility.

Why? Because the visibility of a specific item in this case is not state. It is a result of the state.

Ambroos
  • 3,456
  • 20
  • 27