我有一段可运行的代码,但我有一个最佳实践的问题:我的状态中有一个对象数组,并且用户交互将逐个更改一个对象的值。据我所知,不应直接更改状态,而应始终使用
详细版本: this.state.data 是一个对象数组,表示论坛中主题的列表,Favorite按钮将切换,并调用
setState
。如果我想要避免这种方式,我将通过迭代深克隆数组,然后更改克隆来达到目的。然后将状态设置为克隆。在我看来,避免更改稍后仍要更改的状态只会降低我的性能。详细版本: this.state.data 是一个对象数组,表示论坛中主题的列表,Favorite按钮将切换,并调用
clickCollect()
。
由于我在状态中有一个数组,当我更改一个项目的 is_collected 属性时,我需要创建数组的副本进行操作,并在更改为新值后将其设置为状态。var data = this.state.data.slice(0);
data[index].is_collected = !data[index].is_collected;
this.setState({data: data});
var data = [...this.state.data]
: This makes a shallow clone of the array and ensures that any modifications to data
will not affect this.state.data
.var data = [];
for (var i in this.state.data) {
data.push(this.state.data[i]);
}
然后我更改索引处的值,将其设置为True(当其为False时)或False(当其为True时):data[index].is_collected = !data[index].is_collected;
并更改状态:this.setState({data: data});
考虑到我的数组可能很大或非常大,我猜测这个迭代会降低我的应用程序性能。如果我知道它是正确的方式,我愿意支付这个代价。但是,在这个函数(clickCollect)中,我总是将新值设置为状态,我不等待一个错误的API响应,告诉我停止进行更改。在所有情况下,新值都会进入状态。实际上,我只调用setState让UI重新渲染。所以问题是:
- 在这种情况下我是否需要创建深度克隆?(for var i in ...)
- 如果不需要,假设我的数组包含对象,使用浅拷贝(.slice(0))是否有意义?更改是在数组内部的对象上进行的,因此浅克隆仍会更改我的状态,就像副本(data = this.state.data)一样。
为简单起见删除了我的代码和API调用。
这是初学者的问题,因此完全不同的方法也可以接受。或者给出其他问答链接。
import React from 'react';
var ForumList = React.createClass({
render: function() {
return <div className="section-inner">
{this.state.data.map(this.eachBox)}
</div>
},
eachBox: function(box, i) {
return <div key={i} className="box-door">
<div className={"favorite " + (box.is_collected ? "on" : "off")} onTouchStart={this.clickCollect.bind(null, i)}>
{box.id}
</div>
</div>
},
getInitialState: function() {
return {data: [
{
id: 47,
is_collected: false
},
{
id: 23,
is_collected: false
},
{
id: 5,
is_collected: true
}
]};
},
clickCollect: function(index) {
var data = this.state.data.slice(0);
data[index].is_collected = !data[index].is_collected;
this.setState({data: data});
}
});
module.exports = ForumList;