Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/434.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在反应状态下替换数组中的对象_Javascript_Arrays_Reactjs_Ecmascript 6_Immutability - Fatal编程技术网

Javascript 在反应状态下替换数组中的对象

Javascript 在反应状态下替换数组中的对象,javascript,arrays,reactjs,ecmascript-6,immutability,Javascript,Arrays,Reactjs,Ecmascript 6,Immutability,这个问题可能有点偏向于“最佳实践”问题,但请容忍我 以下是我所在州的一部分: this.state = { typeElements: { headers: [ { name: "h1", size: 70, lineHeight: 1.25, kearning: 0, marginAfter: 0 }, { name: "h2",

这个问题可能有点偏向于“最佳实践”问题,但请容忍我

以下是我所在州的一部分:

this.state = {
  typeElements: {
    headers: [
        {
          name: "h1",
          size: 70,
          lineHeight: 1.25,
          kearning: 0,
          marginAfter: 0
        }, {
          name: "h2",
          size: 70,
          lineHeight: 1.25,
          kearning: 0,
          marginAfter: 0
        }, {
          name: "h3",
          size: 70,
          lineHeight: 1.25,
          kearning: 0,
          marginAfter: 0
        }...
我需要做的是替换headers数组中给定索引处的对象

我不知道如何使用setState方法,如
this.setState(headers[1]={obj})
中所示,但这显然是无效的。我当前的方法是创建一个新数组,然后像下面这样重击旧数组:

_updateStyle(props) {
  let newState = Object.assign({}, this.state)
  newState.typeElements.headers[props.index] = props
  this.setState(newState)
};

对于我的小型黑客项目,我想这没关系,但我觉得这是一个非常繁重的操作,会很快导致任何规模的性能问题。

Object.Assign使用浅拷贝,而不是深拷贝

请注意,在您的示例中,
对象.assign({},this.state)
只复制到
状态
最近的子级的链接,即到
类型元素
,但不会复制
标题
数组

ES6中Object.Assign有一个语法sugar
,Babel有一个特殊的插件


更新:由于这个答案仍然得到支持,请注意,下面的前一个答案对于现代JavaScript和React来说已经过时。“更新”插件现在是遗留的,可以替代使用

React文档还提到了为什么要避免状态突变。对于不可变的更新,您可以使用
Object.assign()
或需要为每一层嵌套执行的更新,如本例中的嵌套
headers
对象及其数组元素。在这个特定的示例中,我们可以使用数组索引作为键,因此也可以使用spread操作符对数组进行浅层克隆,并在克隆的数组中指定一个新对象作为给定索引的值

_updateStyle (props) {
  const { typeElements } = this.state;
  const updatedHeaders = [...typeElements.headers];
  updatedHeaders[props.index] = props;
  this.setState({
    ...this.state,
    typeElements: {
      ...typeElements,
      headers: updatedHeaders
    }
  ));
}
另一个不需要排列语法的解决方案是使用
array.map
创建一个新数组,并返回新对象,而不是给定索引处的旧对象。如果我们不使用数组索引来查找要替换的对象,则需要该解决方案

  const updatedHeaders = typeElements.headers.map((obj, index) => {
    return index === props.index ? props : obj;
  });
Redux文档中的类似示例也解释了这一点

React为此提供了一些不变性帮助,如中所述 文件:

在您的情况下,可以使用$splice命令删除一个项目,然后 在给定索引处添加新索引,例如:

_updateStyle (props) {
  this.setState(update(this.state.typeElements, 
    { $splice: [[props.index, 1, props]] }
  ));
}
使用


你可以在那里找到很好的例子,更好地解释了如何做到这一点

  • 首先,在状态数组中找到要替换的元素的索引
  • 其次,
    更新该索引处的元素
  • 第三,使用新集合调用
    setState

真正地它实际上也为我复制了标题。您能详细说明一下吗?@motleydev Object.assign()方法仅将可枚举和自身属性从源对象复制到目标对象(MDN)。这意味着它只复制最近对象的引用或基本体(数字、字符串)的值。你在实现中得到了旧的数组,如果你对它进行了变异,那么它也会影响到其他使用它的地方。啊哈,我知道这些,但不确定如何实现,所以它在setState方法中?“1”是做什么的?这是新对象的插入点吗?如果是这样的话,我是否可以再次使用props.index呢?请查看array.splice()方法,您将了解。。。数组保存传递给splice方法的参数,因此本例中的“1”是deleteCount。
_updateStyle (props) {
  this.setState(update(this.state.typeElements, 
    { $splice: [[props.index, 1, props]] }
  ));
}
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});
}