我有一个反应组件,我试图将对象传播到构造函数中的状态。
constructor() {
super()
const shapesArray = [1, 2, 3]
let renderStates = shapesArray.map((el, i) => {
return {['shape'+i]: 'black'}
})
this.state = { ...renderStates }
console.log(this.state)
}
我想通过this.state.shape0
访问颜色,
但是当我登录日志this.state
时,我得到了这个:
而不是Object {shape0: "black", shape1: "black", shape2: "black"}
。
我在这里做错了什么?
答案 0 :(得分:3)
这是因为您正在将一个数组传播到一个Object中。数组实际上是具有(通常)顺序积分字符串作为其键的对象。这些键是数组的索引。
如下所示,map
接受一个数组并生成另一个数组
const shapesArray = [1, 2, 3];
const renderStates = shapesArray.map((el, i) => {
return {
['shape' + i]: 'black'
}
});
console.log(renderStates);
当扩展到Object时,源Object中每个自己的可枚举属性的值将在其各自的键下添加到目标。由于数组的键是其索引,因此最终会得到一个Object,其中包含Array的每个元素的属性。每个属性的名称都是数组中的索引。
要实现您的目标,您可以使用Array.prototype.reduce
从数组中构建一个对象,并在映射过程中创建名称。
const shapesArray = [1, 2, 3];
const renderStates = shapesArray
.map((el, i) => {
return {
['shape' + i]: 'black'
}
})
.reduce((o, element) => {
Object.keys(element).forEach(key => o[key] = element[key]);
return o;
}, {});
console.log(renderStates);
当然,通过将对象传播到reduce中,可以更优雅地编写本身。
const shapesArray = [1, 2, 3];
const renderStates = shapesArray
.map((el, i) => {
return {
['shape' + i]: 'black'
}
})
.reduce((o, element) => ({...o, ...element}), {});
console.log(renderStates);
答案 1 :(得分:1)
作为aluan-haddad's answer的优化,reduce可以处理map
中的逻辑
const shapesArray = [1, 2, 3];
const renderStates = shapesArray
.reduce((acc, _, i) => ({
...acc,
['shape' + i]: 'black',
}), {});
console.log(renderStates);
答案 2 :(得分:0)
renderStates
是一个数组,具有从0开始的整数属性或数组索引(如果您想要具体),因此{...renderStates}
将获取每个索引,并创建一个从此索引映射到与该索引对应的值,为了实现您正在寻找的内容,您需要将renderStates
数组缩减为类似的对象
let renderStates = shapesArray.map((el, i) => {
return {['shape'+i]: 'black'}
}).reduce((resultObj, currentShape,index) => resultObj['shape'+index] = currentShape['shape'+index]), { });
renderStates
现在是一个对象,你可以传播它,它会产生你想要的结果
答案 3 :(得分:0)
无需在数组上迭代两次。使用reduce:
const shapesArray = [1, 2, 3];
const renderStates = shapesArray.reduce((accumulator, i) => {
accumulator['shape' + i] = 'black';
return accumulator;
}, {});
console.log(renderStates);