2017-02-22 42 views
1

我有點綠色,當談到ReactJS但它是一個項目我工作的一部分,我想了解如何正確變異組件狀態:渲染行動態地從this.state

我有一個表組件,這是在ES6宣佈爲:

class EmailStatisticTable extends React.Component { 
    constructor (props) { 
     super(props); 
     this.state = { 
      event_id: props.event_id, 
      statistics: [], 
      rows: [] 
     } 
    } 

    componentDidMount() { 
     var self = this; 
     $.getJSON('/events/' + this.state.event_id + '/emails/stats', function(resp){ 
      self.state.statistics = resp; 
      self.state.statistics.forEach(function(statistic) { 
       self.state.rows.push(<EmailStatisticRow statistic={statistic}/>); 
      }); 
     }); 
     console.log(self.state.rows); 
    } 

    render() { 
     return (
      <table className="table table-striped table-hover"> 
       <thead> 
        <tr> 
         <th> Recipient Type </th> 
         <th></th> 
        </tr> 
       </thead> 
       <tbody>{this.state.rows}</tbody> 
      </table> 
     ) 
    } 
} 

這裏的想法是,該行將被動態渲染時this.state.rows變化。我可以看到在componentDidMount方法內的self.state.rows正確地創建了EmailStatisticRow組件的數組。這是下面聲明:

class EmailStatisticRow extends React.Component { 
    constructor(props) { 
     super(props); 
     this.state = { 
      statistic : props.statistic 
     } 
    } 
    render() { 
     return (
      <tr> 
       <td>{this.state.statistic.record_type}</td> 
       <td>{this.state.statistic.count}</td> 
      </tr> 
     ) 
    } 
} 

然而,行從未添加到DOM數據是通過$.getJSON()從服務器發回後。

我認爲我的問題可能是對管理層的基本誤解,也是ReactJS中的可變性/不可變性。

任何人都可以提供一些關於此主題的清晰度?

感謝。

回答

2

您應該通過setState()方法而不是直接設置狀態。

所以更換:

self.state.statistics = resp; 
      self.state.statistics.forEach(function(statistic) { 
       self.state.rows.push(<EmailStatisticRow statistic={statistic}/>); 
      }); 

隨着

this.setState({ 
    statistics: resp 
}) 

然後,而不是分配行,在渲染功能取代

<tbody>{this.state.rows}</tbody> 

<tbody>{this.state.statistics.map(function(row) { 
    return <EmailStatisticRow statistic={row}/> 
})}</tbody> 

編輯:進一步的解釋 - setState將觸發渲染,所有的統計行將被映射到EmailStatisticRow組件。

+1

太棒了。這是我需要向前推進的確切信息。我可以看到我的錯誤現在在哪裏。非常感謝。 – Ohgodwhy

+0

很高興我能幫到你 – paqash

1

在陣營you should not mutate state直接像這樣:

self.state.rows.push(<EmailStatisticRow statistic={statistic}/>); 

相反,使用setState()

self.setState({rows: newRows}); 

這也是not advised to store rendered elements in state<EmailStatisticRow>),只是statistics數據存儲在狀態:

self.setState({statistics: resp}); 

和渲染列表中你render功能,例如使用map()

render() { 
    return (
     <table className="table table-striped table-hover"> 
      <thead> 
       <tr> 
        <th> Recipient Type </th> 
        <th></th> 
       </tr> 
      </thead> 
      <tbody> 
       { this.state.statistics.map(statistic => <EmailStatisticRow statistic={statistic}/>) } 
      </tbody> 
     </table> 
    ) 
} 

使用setState()原因render()被調用,並呈現應該總是給你基礎上,道具和狀態的完整的結果。這是React的基本渲染模式,可以預測。