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

mot*_*dev 10 javascript arrays immutability ecmascript-6 reactjs

对于"最佳实践"问题,这个问题可能有点落空,但请耐心等待.

这是我州的一部分:

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
        }...
Run Code Online (Sandbox Code Playgroud)

我需要做的是在headers数组的给定索引处替换对象.

我不知道如何用setState方法做到这一点this.setState(headers[1] = {obj})- 但这显然是无效的.我当前的方法是创建一个新的数组并破坏旧的数组,如下所示:

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

对于我的小hacky项目,我想这没关系,但我觉得这是非常沉重的,很快就会导致任何规模的性能问题.

Rob*_*man 13

更新:因为这个答案仍然得到了回报,请注意以下的答案已经过时了现代JavaScript和React."更新"插件现在是遗留的,可以使用"immutability-helper"代替.

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
    }
  ));
}
Run Code Online (Sandbox Code Playgroud)

另一个不需要扩展语法的解决方案,如果我们不使用数组索引来找到我们想要替换的对象,则需要使用它array.map来创建一个新数组并在给定索引处返回新对象而不是旧对象.

  const updatedHeaders = typeElements.headers.map((obj, index) => {
    return index === props.index ? props : obj;
  });
Run Code Online (Sandbox Code Playgroud)

Redux文档中的类似示例也解释了"不可变更新模式".

React为此提供了一些不变的帮助,这在文档中有解释:https://facebook.github.io/react/docs/update.html

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

_updateStyle (props) {
  this.setState(update(this.state.typeElements, 
    { $splice: [[props.index, 1, props]] }
  ));
}
Run Code Online (Sandbox Code Playgroud)


dai*_*no3 5

提供如何实现这一目标的更好解释。

  • 首先,在状态数组中找到要替换的元素的索引。
  • 其次,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});
}
Run Code Online (Sandbox Code Playgroud)