【问题标题】:State Not Updating Immediately ReactJS状态没有立即更新 ReactJS
【发布时间】:2015-08-13 03:45:09
【问题描述】:

我无法弄清楚我在这里做错了什么。我有一个事件触发一个函数来改变几个值的状态,这样我就可以触发一个 API 调用;但是,函数第一次运行时状态不会改变。该函数第二次运行时,设置了与前一次运行相比的状态更改。什么可能导致这种延迟?

如下所示,handleFilterChange 接收来自事件的值,我可以验证这些值是否被正确接收;但是,如果我在设置后立即检查状态的值,我可以看到它是未定义的。当事件第二次发生时;但是,我可以看到现在已经发生了原始状态更改,但第二次没有发生。那么为什么要调用两次 setState 才能真正设置状态呢?

var GridView = React.createClass({
  getInitialState: function() {
    window.addEventListener("scroll", this.handleScroll);
    return {
      data: [],
      page: 0,      //for pagination
      loadingFlag: false,
    };
    },

  getMainFeed: function() {

...

 }, //end function
 getFilteredItems: function() {
  ...

}, //end function
  componentWillMount: function() {

  },
  listenForFilterChange: function() {
    window.addEventListener("selectedFilterChange", this.handleFilterChange, false);
  },
  componentWillUnmount: function() {
    window.removeEventListener("selectedFilterChange", this.handleFilterChange, false);
  },
  handleFilterChange: function(filter) {
   //alert(filter.detail.filterType);
   //Convert Data for getFilteredItems
   //(EventType, Category, Buy, Inspiration) {
   switch (filter.detail.filterType) {
     //alert(filter.detail.filterType);
    case 'category':
      this.setState({
        itemCategory: filter.detail.filterSelected,
      });
      break;
    case 'event':
      this.setState({
        eventType: filter.detail.filterSelected,
      });
      break;
    case 'type':
      if (0){
        this.setState({
          filterBuy: 1,
          filterInspiration: 0,
        });
      }
      if (1){
        this.setState({
          filterBuy: 0,
          filterInspiration: 1,
        });
      }
      if (2){
        this.setState({
          filterBuy: 1,
          filterInspiration: 1,
        });
      }
      break;
    case 'trending':
      this.setState({
        itemCategory: filter.detail.filterSelected,
      });
      break;
   }

   this.getFilteredItems();
 },
  componentDidMount: function() {
    this.listenForFilterChange();
...
  },
  handleScroll:function(e){
...
  },
  componentDidUpdate: function() {
...
  },
  render: function() {
      return (
        <div id="feed-container-inner">
          <GridMain data={this.state.data} />
        </div>

      );
    }
  });

【问题讨论】:

    标签: javascript reactjs setstate


    【解决方案1】:

    setState 是异步的,因此更改不会立即反映在状态中:

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

    如果您需要确认状态或根据状态更改执行逻辑,请使用回调参数,如here 所述。

    【讨论】:

    • 谢谢你,@David。我没有意识到,现在这更有意义了。
    【解决方案2】:

    setState 不必调用两次。阅读您的代码,我无法准确推断出问题所在,但我可以建议:

    1. 如果您想知道其中的内容,请在 render 函数中控制台记录您的状态。
    2. 再次检查您的事件中的内容(触发了什么情况以及是否真的触发了)。 3.检查另一个函数(另一个setState)是否没有覆盖您要在handlefilterChange中设置的状态。

    我敢打赌,您的过滤器没有接收到正确的值,首先接收到 undefined filter.detail.filterSelected 然后另一个定义... 检查 filter.detail.filterSelected 中的内容我在评论中看到你只检查了 filter.detail.filterType

    无论如何,您的问题不是由 setState 引起的,而是来自您的数据,我很确定。

    如果有帮助请告诉我

    【讨论】:

    • François,我已经完成了这些检查,原来问题是setState 是异步的,所以我必须使用回调函数。再次感谢您的帮助。
    • 好的,渲染中的 console.log 会起作用,但 Bill Walters 的回答给出了原因并且更准确。
    猜你喜欢
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-02-16
    • 2017-09-05
    • 2022-11-22
    • 2015-03-23
    • 1970-01-01
    相关资源
    最近更新 更多