对于ReactJS
来说,我是绿色的,但它是我正在努力的项目的一部分,我试图了解如何正确改变一个组件状态:
我有一个Table组件,它在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
更改时动态呈现行。我可以看到self.state.rows
方法中的componentDidMount
正确创建了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>
)
}
}
但是,在通过$.getJSON()
从服务器发回数据后,行永远不会添加到DOM中。
我认为我的问题可能是对state
管理层及其在ReactJS中的可变性/不变性的基本误解。
有人能说清楚这个话题吗?
感谢。
答案 0 :(得分: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 :(得分:1)
在React 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的基本渲染模式,使其具有可预测性。