React - 如何按键值更新状态

时间:2017-01-20 13:20:23

标签: javascript reactjs

我正在学习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,但我愿意使用其他库和工具来帮助我。

2 个答案:

答案 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 });
},