繁体   English   中英

如何使用ES6…符号?

[英]How do I use ES6 … notation?

我对React和es6语法相当陌生。 我正在将redux用于我的state.likes Web应用程序,并且在我的reducer中,我希望能够将字符串推入我的state.likes

这是我的代码:

const i = action.index;
console.log(state);
return [
    ...state.slice(0, i), // before the one we are updating
    {...state[i], likes: state[i].likes+1}, //i want to change this bit so I can push deviceKey
    ...state.slice(i+1), //after one we are updating
  ]

当我console.log(state)我在数组中有两个对象,如下所示:

[
{
  "code": "AAAAAAA",
  "caption": "blah blah blah",
  "likes": [
    "ABCDEFG",
    "BACDEFG"
  ],
  "id": "1234567890",
  "display_src": "https://pbs.twimg.com/profile_images/1044686525/Get_Some.jpg"
},
{
  "code": "BBBBBBB",
  "caption": "nah fam",
  "likes": [
    "ABCDEFG",
    "BACDEFG",
    "CBADEFG"
  ],
  "id": "0987654321",
  "display_src": 'http://got-crossfit.com/wp-content/uploads/2014/04/get-some-rest.jpg'
}
]

现在,每当该化state[i].likes器触发时,如何将action.deviceKey推入state[i].likes 我试过{...state[i], likes: state[i].likes.push(action.deviceKey)} ,但是没有用。

还可以有人eli5 ...符号做什么? 我仍然不太明白这是什么意思。

谢谢!

还有,实际上三种不同的方法...都可以使用。 从技术上讲,其中只有一个是有效的官方Javascript,而另两个则很常见。

它们全部用于制作对象和数组的“浅表副本”。 浅表副本是您创建新对象或数组时的内容,但其中包含与原始对象完全相同的项目/数据/引用。

首先, ...可以用作“数组展开”运算符,以制作数组的浅表副本。 到目前为止,这是实际Javascript规范中唯一的形式。 它与Array.slice()基本相同。

其次, ...可以在JSX语法(由React引入,也由其他类似的视图库使用)中使用。 它制作对象的浅表副本。

最后,有一个正式的建议是使用...作为“对象传播”运算符,以在Javascript代码中的任何地方(不仅仅是在JSX中)创建对象的浅表副本。 该建议尚未最终确定,但是许多人通过包含Babel插件将其编译为等效的Object.assign()函数调用来使用它。

对于您的特定问题,我认为您需要使用Array.concat()函数,该函数返回包含新项的新数组引用,而不是Array.push()函数,该函数将该项插入现有数组。

传播算子( ... )并没有完全按照您的想法做。 因此,根据ECMAScript定义,这是一种遍历Objects可枚举属性的方式。 您对状态的设计很糟糕,但是随着增加复杂性,它将变得难以管理。

数组扩展运算符

这只是遍历一个数组,这是从现有数组创建新数组的一种简单方法。 考虑以下:

const old = ['b', 'c'];
const newArr = ['a', ...old, 'd']; // ['a', 'b', 'c', 'd']

您的问题可以通过以下方法解决:

case('ADD_DEVICE_KEY'): {
    return [
        ...state.slice(0, i),
        {...state[i], likes: [...[state[i].likes], action.payload], // We're creating a new array here which is has the values of state[i].likes and also whatever we add to it
        ...state.slice(i+1)
    ]      

** 编辑 **正如Felix Kling在以下评论中指出的那样。 这实际上是一个数组扩展元素


国家设计

您可能会在管理状态时遇到问题,将状态存储为对象要容易得多。

假设您的状态是用户ID,请考虑一下更容易引用的方法:

{
    '1234567890': {
        "code": "AAAAAAA",
        "caption": "blah blah blah",
        "likes": [
            "ABCDEFG",
            "BACDEFG"
        ],
        "display_src": "https://pbs.twimg.com/profile_images/1044686525/Get_Some.jpg"
   },
   1234567890: {
        "code": "BBBBBBB",
        "caption": "nah fam",
        "likes": [
            "ABCDEFG",
            "BACDEFG",
            "CBADEFG"
         ],
         "display_src": 'http://got-crossfit.com/wp-content/uploads/2014/04/get-some-rest.jpg'
    }
]

现在,如果您想使用这些数据,则需要做props[userId]而不是(假设您有一些复杂的逻辑,可以以理智的方式并可以查找用户的方式在其他地方一致地找到ifor(const user of props) { if (user.id === userId) return user } ,第一个是更干净,更容易在子组件中进行分解并且更易于阅读。您让JS编译器为您做到了,我真的不能想出将状态存储为Array的充分理由(特别是在大多数情况下,将Array视为带有数字键的Object)。

这样,您可以使用以下命令轻松添加设备ID:

switch(action.type) {
    case('ADD_DEVICE_ID'): {
        return {
            ...state,
            [action.payload.userId]: Object.assign({}, action.payload.userId, { likes: { deviceId: action.payload.deviceId } })
        }
    }
}

这里我们要重置返回一个新对象,其余状态也一样,包括除了id之外的userId对象。 现在将deviceId字段设置为我们传入的任何内容。一种更简洁,更合理的方法。

spread operator(...)Object.assign可解决此问题

    return 
        [
          ...state.slice(0,i),  // Copy array till index
          Object.assign({},state[i],{likes:state[i].likes+1}),  // update the index array property
          ...state.slice(i+1)   // Copy after the index
        ]

暂无
暂无

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

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