简体   繁体   English

React-如何通过键值更新状态

[英]React - How to update state by key value

I'm in the process of learning React but something I don't fully understand is the best way to update state when you have a large data structure. 我正在学习React,但是我不完全了解的事情是在拥有大型数据结构时更新状态的最佳方法。 Below is a simplified example of what I'm doing, so in my parent component I am setting the state like so 下面是我正在做的简化示例,因此在父组件中,我将状态设置为如下所示

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: []
    }
},

I then have a function in that component to update the description which I pass down to child components using props 然后,我在该组件中有一个函数来更新描述,并使用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 });
},

Then in my render function 然后在我的渲染功能

render: function() {
    return (
        <List items={this.state.items}  update_description={this.update_description} />
    );
}

And my child component 还有我的孩子

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>
    )  
  }
});

This works but it seems very inefficient (especially if you have a large data structure) because the code is looping through all of the items and checking to see if the ID match and if it does it updates the description. 这行得通,但是似乎效率很低(特别是如果您具有大型数据结构),因为代码在所有项目中循环并检查ID是否匹配以及是否更新了描述。 Also with this method if I add another property to each item like "image", I'd then have to remember to update the update_description function. 同样,使用这种方法,如果我向每个项目(如“ image”)添加另一个属性,则必须记住要更新update_description函数。

Ideally I want a way of being about to say "Update the description property where the ID is equal to the one I'm passing into the function". 理想情况下,我希望有一种方式可以说:“更新ID等于我要传递给函数的ID的描述属性”。 Kind of like you do in SQL. 就像您在SQL中一样。

Is this possible? 这可能吗? At the moment I'm only using React but I'm open to using other libraries and tools to help me out. 目前,我仅使用React,但愿意使用其他库和工具来帮助我。

At an algorithmic level, you're maintaining an unordered array of elements and performing a linear search for a particular element. 在算法级别,您要维护元素的无序数组,并对特定元素执行线性搜索。 As you noted, this isn't very efficient. 如您所述,这不是很有效。 Instead of using an array, you should use a hash table which will allow for amortized constant time lookups. 而不是使用数组,您应该使用哈希表,该表将允许摊销恒定时间查找。 In JavaScript, you can use an object, or alternatively, a Map() which was introduced in ES2015 and as such may not be supported by all browsers. 在JavaScript中,您可以使用对象,也可以使用ES2015中引入的Map() ,因此并非所有浏览器都支持。

By using the id as the key to the object/Map, in your update_description() function you can directly access the element associated with that key. 通过使用id作为对象/地图的键,在update_description()函数中,您可以直接访问与该键关联的元素。 Since those elements are objects in this case, you can modify the description property of that particular object. 由于在这种情况下这些元素是对象,因此您可以修改该特定对象的description属性。 You will still need to call this.setState({}) in order for React to re-render. 您仍然需要调用this.setState({})才能重新渲染React。

See setState() for more info on using setState() with mutable data structures. 有关将setState()与可变数据结构结合使用的更多信息,请参见setState()

My answer is not key value, but it is very efficient. 我的答案不是关键值,但它非常有效。 You could just pass the index of item in render function. 您可以只在render函数中传递项目的索引。 I also thought about object with key of id. 我也想到了带有id键的对象。 But you can't make sure the order is what you want when looping. 但是您不能确保循环时的顺序是您想要的。

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>
    )  
  }
});

And pass it to update_description then you can use index to update description. 并将其传递给update_description,然后可以使用索引来更新描述。

update_description: function(index, description) {
    var items = this.state.items;
    items[index].description = description;
    this.setState({ items: state });
},

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM