我正在学习React,但我不完全理解的是当你拥有大型数据结构时更新状态的最佳方法。下面是我正在做的事情的简化示例,所以在我的父组件中我设置状态如此
getInitialState: function(){
return {
initialItems: [
{"id": 1, "name": "Apples", "description": "Description"},
{"id": 2, "name": "Broccoli", "description": "Description"},
{"id": 3, "name": "Chicken", "description": "Description"},
{"id": 4, "name": "Duck", "description": "Description"}
],
items: []
}
},
然后我在该组件中有一个函数来更新我使用props
传递给子组件的描述update_description: function(id, description) {
var state = this.state.items.map(function(item) {
return {
id: item.id,
name: item.name,
description: (item.id === id ? description: item.description),
};
}, this);
this.setState({ items: state });
},
然后在我的渲染功能
中render: function() {
return (
<List items={this.state.items} update_description={this.update_description} />
);
}
我的孩子组件
var List = React.createClass({
render: function(){
return (
<ul className="no-list no-pad items">
{
this.props.items.map(function(item) {
return <ListItem key={item.id} item={item} update_description={this.props.update_description} />
}, this)
}
</ul>
)
}
});
这可行,但效果似乎非常低效(特别是如果你有一个大型数据结构),因为代码循环遍历所有项目并检查ID是否匹配,如果它匹配则更新描述。另外使用这种方法,如果我为每个项目添加另一个属性,如“image”,那么我必须记住更新update_description
函数。
理想情况下,我想要一种方式来说“更新描述属性,其中ID等于我传入函数的那个”。有点像你在SQL中做的。
这可能吗?目前我只使用React,但我愿意使用其他库和工具来帮助我。
答案 0 :(得分:2)
在算法级别,您需要维护无序的元素数组并对特定元素执行线性搜索。如你所知,这并不是非常有效。您应该使用哈希表,而不是使用数组,这将允许分摊的常量时间查找。在JavaScript中,您可以使用对象,或者使用ES2015中引入的Map(),因此可能并非所有浏览器都支持。
通过使用id作为对象/ Map的键,在update_description()
函数中,您可以直接访问与该键关联的元素。由于这些元素在这种情况下是对象,因此您可以修改该特定对象的description
属性。您仍然需要调用this.setState({})
才能重新呈现React。
有关将setState()
与可变数据结构一起使用的详情,请参阅setState()。
答案 1 :(得分:0)
我的回答不是关键值,但它非常有效。 你可以在render函数中传递item的索引。 我也想到了带有id键的对象。但是你无法确保循环时顺序是你想要的。
var List = React.createClass({
render: function(){
return (
<ul className="no-list no-pad items">
{
this.props.items.map(function(item, index) {
return <ListItem key={item.id} item={item} index={index} update_description={this.props.update_description} />
}, this)
}
</ul>
)
}
});
并将其传递给update_description,然后您可以使用索引来更新说明。
update_description: function(index, description) {
var items = this.state.items;
items[index].description = description;
this.setState({ items: state });
},