React setState not working on first try, but working for a second?

I have a handleSelection method that is called when the button is clicked, however, if I press the button as soon as the state is set, when it reaches this.setState({selectedFoods: newSelections}); . Everything else in the method works correctly (as my various console.logs suggest to me :)). When the button is pressed a second time, everything in the method will be executed again, and setState will work.

 var Flavor = React.createClass({ getInitialState: function() { return { foods: {}, selectedFoods: [], affinities: [] }; }, componentDidMount: function() { $.ajax({ url: this.props.url, dataType: 'json', cache: false, success: function(data) { this.setState({foods: data}); }.bind(this), error: function(xhr, status, err) { console.error(this.props.url, status, err.toString()); }.bind(this) }); }, componentDidUpdate: function () { $('#select-food').selectize({ onChange: this.handleSelection } ); }, handleSelection: function (e) { if (e.target) { var selectedFood = e.target.id; } else { var selectedFood = e; } console.log(selectedFood); if (this.state.foods[selectedFood]) { var selections = this.state.selectedFoods; var newSelections = selections.concat(selectedFood); console.log("newSelections: "+newSelections) var state = Object.assign(this.state, {selectedFoods: newSelections}); this.setState(state); console.log("state: "+this.state.selectedFoods) this.handleAffinities(); } else { console.log("** "+selectedFood+" **"); } }, handleAffinities: function() { console.log("selectedFoods: "+this.state.selectedFoods.length) if (this.state.selectedFoods.length > 0) { var allAffinities = this.state.selectedFoods.map((food) => { return this.state.foods[food]; }); console.log(allAffinities.length); console.log(allAffinities); var commonAffinities = allAffinities[0]; allAffinities.forEach((affinities) => { commonAffinities = commonAffinities.filter((n) => { return affinities.indexOf(n) != -1; }); }) this.setState({affinities: commonAffinities}); } else { this.setState({ affinities: [] }); } }, handleRemove: function(food) { var selectedFoods = this.state.selectedFoods; var index = selectedFoods.indexOf(food); var updatedSelection = selectedFoods.splice(index, 1); this.setState({selectedFoods: selectedFoods}); this.handleAffinities(); }, 

Why is everything running correctly for the first time except my setState function? And why does this work when pressed a second time?

+6
source share
1 answer

The condition changes exactly as expected. The problem is that your console.log setState run immediately after calling setState before the new state is set.

From docs :

setState() does not immediately mutate this.state , but creates a pending state transition. Access to this.state after calling this method can potentially return an existing value.

If you want to run the console.log statement after the state transition is complete, pass the function as the setState() .

 this.setState({selectedFoods: newSelections}, () => { console.log(this.state.selectedFoods); }); 
+18
source

All Articles