React组件不会在状态更改时重新呈现吗?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (430)

我有一个React类,它将通过API来获取内容。我已经确认数据会回来,但不是重新渲染:

var DealsList = React.createClass({
  getInitialState: function() {
    return { deals: [] };
  },
  componentDidMount: function() {
    this.loadDealsFromServer();
  },
  loadDealsFromServer: function() {
    var newDeals = [];

    chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) {
      newDeals = deals;
    });

    this.setState({ deals: newDeals });
  },
  render: function() {
    var dealNodes = this.state.deals.map(function(deal, index) {
      return (
        <Deal deal={deal} key={index} />
      );
    });
    return (
      <div className="deals">
        <table>
          <thead>
            <tr>
              <td>Name</td>
              <td>Amount</td>
              <td>Stage</td>
              <td>Probability</td>
              <td>Status</td>
              <td>Exp. Close</td>
            </tr>
          </thead>
          <tbody>
            {dealNodes}
          </tbody>
        </table>
      </div>
    );
  }
});

但是,如果我在debugger下面添加一个类似的内容,newDeals则会填充该内容,然后一旦我继续,就会看到数据:

  loadDealsFromServer: function() {
    var newDeals = [];

    chrome.runtime.sendMessage({ action: "findDeals", personId: this.props.person.id }, function(deals) {
      newDeals = deals;
    });
    debugger
    this.setState({ deals: newDeals });
  },

这就是所谓的优惠活动列表:

var Gmail = React.createClass({
  render: function() {
    return (
      <div className="main">
        <div className="panel">
          <DealsList person={this.props.person} />
        </div>
      </div>
    );
  }
});
提问于
用户回答回答于

这是因为来自于chrome.runtime.sendMessage异步的响应; 这里是操作的顺序:

var newDeals = [];

// (1) first chrome.runtime.sendMessage is called, and *registers a callback*
// so that when the data comes back *in the future*
// the function will be called
chrome.runtime.sendMessage({...}, function(deals) {
  // (3) sometime in the future, this function runs,
  // but it's too late
  newDeals = deals;
});

// (2) this is called immediately, `newDeals` is an empty array
this.setState({ deals: newDeals });

当您使用调试器暂停脚本时,将给予延长时间来调用回调; 当你继续时,数据已经到达,它似乎工作。

要解决此问题,需要setState在Chrome扩展程序返回数据后进行通话:

var newDeals = [];

// (1) first chrome.runtime.sendMessage is called, and *registers a callback*
// so that when the data comes back *in the future*
// the function will be called
chrome.runtime.sendMessage({...}, function(deals) {
  // (2) sometime in the future, this function runs
  newDeals = deals;

  // (3) now you can call `setState` with the data
  this.setState({ deals: newDeals });
}.bind(this));
用户回答回答于

我想补充一下这个非常简单但很容易犯的错误:

this.state.something = 'changed';

...然后不理解为什么它不是渲染和谷歌搜索,并进入这个页面,只是意识到你应该写:

this.setState({something: 'changed'});

如果使用setState更新状态,React只会触发重新渲染。

扫码关注云+社区

领取腾讯云代金券

玩转腾讯云 有奖征文活动