Javascript 在 ReactJS 中更新数组中的对象的最佳方法是什么?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28121272/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-23 01:14:59  来源:igfitidea点击:

Whats the best way to update an object in an array in ReactJS?

javascriptreactjs

提问by Alex Black

If you have an array as part of your state, and that array contains objects, whats an easy way to update the state with a change to one of those objects?

如果您有一个数组作为状态的一部分,并且该数组包含对象,那么通过更改这些对象之一来更新状态的简单方法是什么?

Example, modified from the tutorial on react:

示例,从关于 react 的教程修改而来:

var CommentBox = React.createClass({
  getInitialState: function() {
    return {data: [
      { id: 1, author: "john", text: "foo" },
      { id: 2, author: "bob", text: "bar" }
    ]};
  },
  handleCommentEdit: function(id, text) {
    var existingComment = this.state.data.filter({ function(c) { c.id == id; }).first();
    var updatedComments = ??; // not sure how to do this  

    this.setState({data: updatedComments});
  }
}

采纳答案by nilgun

While updating state the key part is to treat it as if it is immutable. Any solution would work fine if you can guarantee it.

在更新状态时,关键部分是将其视为不可变的。如果您可以保证,任何解决方案都可以正常工作。

Here is my solution using immutability-helper:

这是我使用immutability-helper 的解决方案:

jsFiddle:

js小提琴

  var update = require('immutability-helper');

  handleCommentEdit: function(id, text) {
    var data = this.state.data;
    var commentIndex = data.findIndex(function(c) { 
        return c.id == id; 
    });

    var updatedComment = update(data[commentIndex], {text: {$set: text}}); 

    var newData = update(data, {
        $splice: [[commentIndex, 1, updatedComment]]
    });
    this.setState({data: newData});
  },

Following questions about state arrays may also help:

以下有关状态数组的问题也可能有所帮助:

回答by Not loved

I quite like doing this with Object.assign rather than the immutability helpers.

我非常喜欢用 Object.assign 而不是不变性助手来做这件事。

handleCommentEdit: function(id, text) {
    this.setState({
      data: this.state.data.map(el => (el.id === id ? Object.assign({}, el, { text }) : el))
    });
}

I just think this is much more succinct than splice and doesn't require knowing an index or explicitly handling the not found case.

我只是认为这比 splice 简洁得多,并且不需要知道索引或明确处理未找到的情况。

If you are feeling all ES2018, you can also do this with spread instead of Object.assign

如果你对 ES2018 有感觉,你也可以用 spread 而不是 Object.assign

this.setState({
  data: this.state.data.map(el => (el.id === id ? {...el, text} : el))
});

回答by daino3

Trying to clean up/ explain better how to do this AND what's going on.

试图清理/更好地解释如何做到这一点以及发生了什么。

  • First, find the index of the element you're replacing in the state array.
  • Second, updatethe element at that index
  • Third, call setStatewith the new collection
  • 首先,在状态数组中找到要替换的元素的索引。
  • 其次,update该索引处的元素
  • 三、setState用新收藏打电话
import update from 'immutability-helper';

// this.state = { employees: [{id: 1, name: 'Obama'}, {id: 2, name: 'Trump'}] } 

updateEmployee(employee) {
    const index = this.state.employees.findIndex((emp) => emp.id === employee.id);
    const updatedEmployees = update(this.state.employees, {$splice: [[index, 1, employee]]});  // array.splice(start, deleteCount, item1)
    this.setState({employees: updatedEmployees});
}

Edit: there's a much better way to do this w/o a 3rd party library

编辑:有一个更好的方法来做这个 w/oa 3rd 方库

    const index = this.state.employees.findIndex(emp => emp.id === employee.id),
          employees = [...this.state.employees] // important to create a copy, otherwise you'll modify state outside of setState call
    employees[index] = employee;
    this.setState({employees});

回答by Umair Ahmed

You can do this with multiple way, I am going to show you that I mostly used. When I am working with arrays in react usually I pass a custom attribute with current index value, in the example below I have passed data-index attribute, data- is html 5 convention.

您可以通过多种方式做到这一点,我将向您展示我最常用的方法。当我在 React 中使用数组时,通常我传递一个带有当前索引值的自定义属性,在下面的示例中,我传递了 data-index 属性,data- 是 html 5 约定。

Ex:

前任:

//handleChange method.
handleChange(e){
  const {name, value} = e,
        index = e.target.getAttribute('data-index'), //custom attribute value
        updatedObj = Object.assign({}, this.state.arr[i],{[name]: value});
      
  //update state value.
  this.setState({
    arr: [
      ...this.state.arr.slice(0, index),
      updatedObj,
      ...this.state.arr.slice(index + 1)
    ]
  })
  }