【问题标题】:Working with Spread Syntax ES6使用扩展语法 ES6
【发布时间】:2017-08-19 06:57:27
【问题描述】:

我正在使用扩展语法替换数组中的对象,但我无法将该对象添加为数组的新条目。

state = {8xf0y6ziyjabvozdd253nd:[
  {
    "id": "894tuq4ut84ut8v4t8wun89g",
    "parentId": "8xf0y6ziyjabvozdd253nd",
    "timestamp": 1503045227866,
    "body": "Hi there! I ams a COMMENTSsg.",
    "author": "thingtwo",
    "voteScore": 143,
    "deleted": false,
    "parentDeleted": false
  },
]}

首先我找到我想用这个函数替换的元素的索引:

let index = state[payload.id].findIndex((element)=> element.id === payload.data.id)

然后我使用扩展语法创建一个新状态并替换数组内部的元素:

return { ...state,
                [payload.id]:[...state[payload.id],index=payload.data]
            }

但它会返回这个:

    {8xf0y6ziyjabvozdd253nd:[
          {
            "id": "894tuq4ut84ut8v4t8wun89g",
            "parentId": "8xf0y6ziyjabvozdd253nd",
            "timestamp": 1503045227866,
            "body": "Hi there! I am a COMMENTS.",
            "author": "thingtwo",
            "voteScore": 143,
            "deleted": false,
            "parentDeleted": false
          },
          {
            "id": "894tuq4ut84ut8v4t8wun89g",
            "parentId": "8xf0y6ziyjabvozdd253nd",
            "timestamp": 1503045227866,
            "body": "Hi there! I am a COMMENTS Replace",
            "author": "thingtwo",
            "voteScore": 143,
            "deleted": false,
            "parentDeleted": false
          }
        ]}

预期输出:

{8xf0y6ziyjabvozdd253nd:[
              {
                "id": "894tuq4ut84ut8v4t8wun89g",
                "parentId": "8xf0y6ziyjabvozdd253nd",
                "timestamp": 1503045227866,
                "body": "Hi there! I am a COMMENTS Replace",
                "author": "thingtwo",
                "voteScore": 143,
                "deleted": false,
                "parentDeleted": false
              }
            ]}

【问题讨论】:

  • 没有“扩展运算符”。有“扩展语法”或“扩展符号”。实际上有“数组扩展语法”和“对象扩展语法”,所以弄清楚你在说什么会很有用。
  • 你能添加预期的输出吗?
  • data in index=data 是什么...你想将data 的值分配给index吗?
  • @torazaburo 我猜这取决于..docs.microsoft.com/en-us/scripting/javascript/reference/…,不知何故,MDN URL 以/Operators/Spread_operator 结尾
  • 谢谢,说我是“扩展语法”而不是“扩展运算符”,我编辑了问题,并包含了预期的输出。

标签: javascript


【解决方案1】:

您可以使用Object.assign 更新找到的对象的属性(使用Array#find)。

let object = state[payload.id].find((element)=> element.id === payload.data.id);

Object.assign(object, payload.data);

【讨论】:

  • 我支持这个答案。事实上,我正在研究一些类似的示例,您可以在数组传播用法中看到包含快速修复的示例:jsbin.com/dolodof/edit?js,console
【解决方案2】:

扩展语法/运算符用于将对象扩展为逗号分隔的键。

在您的状态下,每个键都是有效负载 id,您希望替换该有效负载值中的一个条目,该值是一个数组。因此,您需要通过 id 转到该有效负载,转到该有效负载值数组中的索引并将该值替换为新值。下面的代码应该会给你预期的输出,

let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
state[payload.id][index] = payload.data;
console.log(state);

当您想要替换该有效负载的完整数组时,您应该使用扩展语法,并且在这里您想要替换该数组中的条目而不是完整数组。

编辑以避免突变

1.使用 Object.assign 会改变状态,

let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
let stateCopy = Object.assign({}, state);
stateCopy[payload.id][index] = payload.data;
console.log(state);
console.log(stateCopy);

检查 state 和 stateCopy 是否被修改

2。使用扩展语法会改变状态,

let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
let stateCopy = {...state}
stateCopy[payload.id][index] = payload.data;
console.log(state);
console.log(stateCopy);

检查 state 和 staeteCopy 是否被修改

3.使用克隆避免原始状态的突变,

安装esclone,

 #> npm install --savedev esclone

转到您的文件并添加导入,

 import esclone from "esclone";

并使用下面的代码来实现预期的输出而不发生变异,

let index = state[payload.id].findIndex((element)=> element.id === payload.data.id);
let stateCopy = esclone(state);
stateCopy[payload.id][index] = payload.data;
console.log(state);
console.log(stateCopy);

检查原始状态没有被修改

注意: Object.assign & spread 语法只执行引用复制而不执行深度复制,因此您需要使用一些深度克隆机制,如 esclone 库。 p>

【讨论】:

  • 但是你正在改变状态,是因为我使用传播语法,我不想改变状态
  • 最后,扩展运算符和 object.assign 进行了浅拷贝。我会检查是否可以根据您的需要改进我的答案。您可能需要使用克隆来避免突变。
  • 抱歉,如果你这样做我不同意:let state = {id:1, name:"james"}let newState = {...state}newState.id = 2console.log(state.id) // -->1console.log(Newstate.id) -->2这意味着状态永远不会使用 Spread 发生变异。
  • 您的意思是,您不同意扩展运算符执行浅拷贝?
  • 是的,它返回一个新对象。
猜你喜欢
  • 2017-12-24
  • 2020-02-24
  • 2023-03-06
  • 1970-01-01
  • 2017-07-27
  • 2018-05-01
  • 2019-01-28
相关资源
最近更新 更多