Babel.js Spread语法未按预期处理对象数组

yizd12fk  于 2023-06-20  发布在  Babel
关注(0)|答案(4)|浏览(197)

我有一个react组件,我试图将对象扩展到构造函数中的状态。

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"}
我做错了什么?

nwsw7zdq

nwsw7zdq1#

这是因为你正在将数组扩展到对象中。数组实际上是以(通常)连续整数 * 字符串 * 作为键的对象。这些键是数组的索引。
如下所示,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从数组构建一个对象,该对象具有在Map过程中创建的名称。

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);
ny6fqffe

ny6fqffe2#

作为对aluan-haddad's answer的优化,reduce可以处理map中的逻辑。

const shapesArray = [1, 2, 3];

const renderStates = shapesArray
  .reduce((acc, _, i) => ({
    ...acc,
    ['shape' + i]: 'black',
  }), {});

console.log(renderStates);
deyfvvtc

deyfvvtc3#

renderStates是一个数组,它具有从0开始的整数属性,或者如果你想具体一些,可以使用数组索引,所以{...renderStates}将获取每个索引,并创建一个从该索引到该索引对应的值的Map,为了实现你想要的,你需要将你的renderStates数组缩减为这样的对象

let renderStates = shapesArray.map((el, i) => {
        return {['shape'+i]: 'black'}
    }).reduce((resultObj, currentShape,index) => resultObj['shape'+index] = currentShape['shape'+index]), { });

renderStates现在是一个对象,你可以展开它,它会产生你想要的结果

8i9zcol2

8i9zcol24#

不需要在数组上迭代两次。使用减少:

const shapesArray = [1, 2, 3];

const renderStates = shapesArray.reduce((accumulator, i) => {
  accumulator['shape' + i] = 'black';
  return accumulator;
}, {});

console.log(renderStates);

相关问题