[英]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]
而不是(假设您有一些复杂的逻辑,可以以理智的方式并可以查找用户的方式在其他地方一致地找到i
; for(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.