简体   繁体   English

React setState 在第一次尝试时不起作用,但在第二次尝试时有效?

[英]React setState not working on first try, but works on second?

I have the handleSelection method called when a button is clicked, however, if I click the button once the state does not get set when it gets to this.setState({selectedFoods: newSelections});我在单击按钮时调用了handleSelection方法,但是,如果在状态未设置时单击该按钮,当它到达this.setState({selectedFoods: newSelections}); . . Everything else in the method executes correctly (as my various console.logs tell me :) ).该方法中的其他所有内容都正确执行(正如我的各种 console.logs 告诉我的 :) )。 When the button is clicked a second time, everything in the method gets executed again and the setState works.当第二次单击按钮时,方法中的所有内容都会再次执行并且setState起作用。

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 does everything execute correctly the first time except my setState function?为什么除了我的setState函数之外,一切都第一次正确执行? And why it work on the second click?为什么它在第二次点击时起作用?

The state is changing exactly the way it is supposed to.国家正在按照预期的方式改变。 The problem is that your console.log statements immediately after your call to setState are firing before the new state is set.问题是在您调用setState之后,您的console.log语句会在设置新状态之前立即触发。

From the docs :文档

setState() does not immediately mutate this.state but creates a pending state transition. setState()不会立即改变this.state而是创建一个挂起的状态转换。 Accessing this.state after calling this method can potentially return the existing value.调用此方法后访问this.state可能会返回现有值。

If you'd like to fire a console.log statement after the state transition completes, pass a function as a callback to setState() .如果您想在状态转换完成后触发console.log语句,请将函数作为回调传递给setState()

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

As @Micheal stated, setState function stays pending, and first console.log works.正如@Micheal 所说, setState 函数保持挂起,第一个 console.log 起作用。 Anybody who wants to see or experiment this situation, may have a look at my codesandbox.io example .任何想要看到或试验这种情况的人,可以看看我的代码和盒子.io 示例 Here, inside YesNoComponentWithClass, yes button logs empty for the first click, while no button logs the expected value.在这里,在 YesNoComponentWithClass 中,第一次单击时 yes 按钮记录为空,而 no 按钮记录预期值。

I also suffered from this problem for a day and got the solution.我也被这个问题困扰了一天并得到了解决方案。 I just added in myCode the componentDidUpdate() method , and now everything working well.我刚刚在 myCode 中添加了 componentDidUpdate() 方法,现在一切正常。 For the flow of the life cycle check out the life cycle image given in link.对于生命周期的流程,请查看链接中给出的生命周期图像。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM