【问题标题】:React setState not working on first try, but works on second?React setState 在第一次尝试时不起作用,但在第二次尝试时起作用?
【发布时间】:2016-10-17 06:04:11
【问题描述】:

我在单击按钮时调用了handleSelection 方法,但是,如果我单击按钮,一旦状态未设置为this.setState({selectedFoods: newSelections});。该方法中的其他所有内容都正确执行(正如我的各种 console.logs 告诉我的那样:))。第二次单击该按钮时,方法中的所有内容都会再次执行,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();
  },

为什么除了我的setState 函数之外的所有东西第一次都能正确执行?为什么它在第二次点击时起作用?

【问题讨论】:

  • 您的if (this.state.foods[selectedFood]) 是否因某种原因无效?也许this.state.foods 第一次还是空的还是类似的?
  • 您的getInitialState 函数中有什么?你可以发布整个组件,也许在 JSFiddle 中?
  • 谢谢,我把所有东西都加到了 render 方法中
  • 我可以通过替换它来让它工作:var state = Object.assign(this.state, {selectedFoods: newSelections}); this.setState(state);
  • 这能回答你的问题吗? setState doesn't update the state immediately

标签: javascript reactjs setstate


【解决方案1】:

状态正在按照应有的方式发生变化。问题是,在您调用 setState 之后,您的 console.log 语句会在新状态设置之前触发。

来自docs

setState() 不会立即改变this.state,而是创建一个挂起的状态转换。调用此方法后访问this.state 可能会返回现有值。

如果您想在状态转换完成后触发console.log 语句,请将函数作为回调传递给setState()

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

【讨论】:

  • 这真是太好了。我的组件状态也没有得到更新,因为 DOM 没有按预期改变。
  • 请注意:我正在为一个切换函数而苦苦挣扎,我需要这样的东西:“在 this.setState 之后我需要一个函数来触发。我通过在正如@Michael 所说,setState 回调,效果非常好。
  • 谢谢!我有一段时间试图弄清楚这一点。现在我所有的 setState 都使用了回调,我没有任何问题。
  • 优秀的答案。它帮助了我的代码;现在我可以在 setState 设置后立即提出请求。 :)
  • 非常感谢。
【解决方案2】:

我也被这个问题困扰了一天,得到了解决方案。 我刚刚在 myCode 中添加了 componentDidUpdate() 方法,现在一切正常。 有关生命周期的流程,请查看链接中给出的生命周期图像。

【讨论】:

    【解决方案3】:

    正如@Micheal 所说,setState 函数保持挂起状态,并且第一个 console.log 有效。任何想看到或尝试这种情况的人都可以看看我的codesandbox.io example。在这里,在 YesNoComponentWithClass 中,第一次单击时 yes 按钮记录为空,而 no 按钮记录预期值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-06-04
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-02-28
      • 1970-01-01
      相关资源
      最近更新 更多