数组总是在每个元素中获取最后一个值

时间:2019-02-08 12:41:53

标签: javascript reactjs

在循环中,我创建一个新变量,并在每次循环时(显然)设置一个新值

但是,当循环完成并且在循环之外时,我console.log()将数组填充到循环中。它使用最后一个元素的值记录每个元素。

我尝试使用.push()来填充数组。

state = {
    dates: ['2019-02-04', '2019-02-05', '2019-02-06'],
    entry: {
        value1: undefined,
        value2: undefined,
        value3: {
            value3_1: undefined,
            value3_2: undefined
        },
        date: undefined
    }
}

functionToFillArray() {
    let entries = [],
        entry = this.state.entry;

        entry.value1 = 'value1';
        entry.value2 = 'value2';
        entry.value3 = {
            value3_1: 'value3_1',
            value3_2: 'value3_2'
        };

    this.state.dates.forEach((date, i) => {
        entry.date = date;

        entries.push(entry);
    });

    console.log(entries);
}

我期望的输出是:

[
    {
        value1: 'value1',
        value2: 'value2',
        value3: {
            value3_1: 'value3_1',
            value3_2: 'value3_2'
        },
        date: '2019-02-04'
    },
    {
        value1: 'value1',
        value2: 'value2',
        value3: {
            value3_1: 'value3_1',
            value3_2: 'value3_2'
        },
        date: '2019-02-05'
    },
    {
        value1: 'value1',
        value2: 'value2',
        value3: {
            value3_1: 'value3_1',
            value3_2: 'value3_2'
        },
        date: '2019-02-06'
    }
]

我得到的值(总是相同的日期):

[
    {
        value1: 'value1',
        value2: 'value2',
        value3: {
            value3_1: 'value3_1',
            value3_2: 'value3_2'
        },
        date: '2019-02-06'
    },
    {
        value1: 'value1',
        value2: 'value2',
        value3: {
            value3_1: 'value3_1',
            value3_2: 'value3_2'
        },
        date: '2019-02-06'
    },
    {
        value1: 'value1',
        value2: 'value2',
        value3: {
            value3_1: 'value3_1',
            value3_2: 'value3_2'
        },
        date: '2019-02-06'
    }
]

4 个答案:

答案 0 :(得分:0)

您的代码在每次迭代中都会更改相同的this.state.entry对象,并将该单个对象引用一次又一次地推送到数组,因此最后该数组确实包含多个条目,但是所有具有相同的对象引用。

总而言之,this.state.entry值(您似乎想像模板一样使用)实际上没有任何作用。无论如何,您正在为其属性的 all 指定新值。因此,似乎没有必要。

只需替换一下:

let entry = this.state.entry;

具有:

let entry = {};

现在entry将成为每次迭代中新创建的对象。

更新的问题-更新的答案

在对问题进行编辑之后,您一次又一次地为 same 对象分配一个date属性。

原理保持不变。现在替换它:

functionToFillArray() {
    let entries = [],
        entry = this.state.entry;
    entry.value1 = 'value1';
    entry.value2 = 'value2';
    entry.value3 = {
        value3_1: 'value3_1',
        value3_2: 'value3_2'
    };
    this.state.dates.forEach((date, i) => {
        entry.date = date;
        entries.push(entry);
    });
    console.log(entries);
}

...具有:

functionToFillArray() {
    let entries = this.state.dates.map((date, i) => {
        return {
            value1: 'value1',
            value2: 'value2',
            value3: {
                value3_1: 'value3_1',
                value3_2: 'value3_2'
            },
            date
        };
    });
    console.log(entries);
}

这样,您可以在每次迭代中创建一个新对象。首先初始化一个对象,然后覆盖它的每个属性是没有好处的,因为那时您仍在使用单个对象。每次迭代都需要一个新的。

请注意,数组的map方法在这里比forEach更有用,但与您的问题无关。

答案 1 :(得分:0)

使用解构。

const state = {
  dates: ['2019-02-04', '2019-02-05', '2019-02-06'],
  entry: {
    value1: undefined,
    value2: undefined,
    value3: {
      value3_1: undefined,
      value3_2: undefined
    },
    date: undefined
  }
};

function ToFillArray() {
  let entries = [];

  state.dates.forEach((date, i) => {
    const entry = {
      ...state.entry,
      value1: 'value1',
      value2: 'value2',
      value3: {
        value3_1: 'value3_1',
        value3_2: 'value3_2'
      },
      date
    };

    entries.push(entry);
  });

  console.log(entries);
}

ToFillArray();

答案 2 :(得分:0)

您不是要创建副本,而是要创建到this.state.entry的链接,然后再创建循环对象。 尝试先创建副本。

...
this.state.dates.forEach((date, i) => {
        let entry = {...this.state.entry};
...

答案 3 :(得分:-1)

这是因为您总是引用相同的变量,而不是复制变量,修改状态,而是尝试以下操作:

let stateCopy= {...this.state};
let entry = stateCopy.entry

    entry.value1 = 'value1';
    entry.value2 = 'value2';
    entry.value3 = {
        value3_1: 'value3_1',
        value3_2: 'value3_2'
    };
    entry.date = date;

    entries.push(entry);

您可以参考this article以获得更详细的说明:)

在这种特殊情况下,由于您每次都分配属性,因此实际上并没有必要在状态下重用对象