2014-09-19 172 views
17

我有一个React类,它将通过API来获取内容。我已确认该数据是回来了,但它不是重新渲染:React组件不会在状态更改时重新渲染

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> 
    ); 
    } 
}); 

回答

8

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

​​

当你用调试器暂停脚本时,你给了扩展时间来调用回调;当你继续时,数据已经到达,它似乎工作。

要解决,你想要做的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)); 
+0

呃!当调试器线修复它时,我应该知道这种情况。当我第一次尝试这个时,绑定(这个)是我错过的东西。谢谢,非常详细的评论! – brandonhilkert 2014-09-19 15:54:37

32

我想添加到这个的极大简单,但是是如此容易犯的错误写作:

this.state.something = 'changed'; 

...然后不明白为什么它不渲染和谷歌搜索,并在此页的到来,只有认识到,你应该写:

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

如果您使用setState更新状态,则React仅触发重新呈现。

+0

这是我遇到的确切问题。奇怪的是,他们没有发出警告,因为他们在尝试更新道具时会抛出一个警告。 – AndrewJM 2015-12-13 22:38:37

+0

谢谢好先生 – heinst 2016-05-02 14:04:40

+0

@AndrewJM他们不能发出警告。他们可以,如果你写'this.state ='something'',因为你会碰到'state'的setter,但是在上面的例子中,代码碰到了getter,它返回一个对象,然后结束设置一个对象上的字段只是状态的一个副本。 – 2017-06-23 21:37:07

6

另一个非常容易的错误,这是我的问题的根源:我写了自己的shouldComponentUpdate方法,它没有检查我添加的新状态更改。

相关问题