我正在尝试更新对象的嵌套数组的状态,例如添加到results [0] .rooms [2]->循环房间->并添加到每个对象room.sunday.flag
array of results:
results: [
{ dates:
{ weekstart: 2018-08-26T04:00:00.000Z,
weekend: 2018-09-02T03:59:59.000Z,
daysofweek: [Array] },
need: [ '103', '204', '12', '234', '34', '555', '44' ],
backorder:
[ '100', '102', '150', '403', '344', '12', '3434', '23', '44' ],
_id: 5b7b139465c29145d8d69ac2,
iscurrent: true,
isnext: false,
rooms: [ [Object], [Object], [Object], [Object] ],
user: 5b61b782719613486cdda7ec,
__v: 9 },
{ dates:
{ weekstart: 2018-09-02T04:00:00.000Z,
weekend: 2018-09-09T03:59:59.000Z,
daysofweek: [Array] },
need: [ '12', '13', '55', '45' ],
backorder: [ '10', '11', '112' ],
_id: 5b83fdc500b6b6dc493e9bb8,
iscurrent: false,
isnext: true, rooms: [ [Object], [Object], [Object],
[Object] ],
user: 5b61b782719613486cdda7ec,
__v: 9 }
]
我尝试更改状态而不进行更改
const resultsRooms = [
...this.state.results[0].rooms ];
const rooms = resultsRooms.map((room, roomIndex) =>
{
room.sunday.flag = true;
});
const resultsUpdaye = this.results.forEach((element, index) => {
if (index === 0) {
elsment.rooms = rooms;
}
});
this.setState({
results: resultsUpdaye
});
有什么帮助吗?我在做什么错了
答案 0 :(得分:3)
您的resultsRooms.map
是错误的。首先,它不返回对象。如果使用箭头函数并要返回对象,则必须用括号将其括起来。
const foo = () => ( { foo: "bar" } );
如果不这样做,该函数会将{}
视为正文。
您的第二个问题是,map
返回一个数组,不对项目执行任何操作。所以你不能这样做:room.sunday.flag = true;
这是工作版本:
const rooms = resultsRooms.map((room, roomIndex) =>
( { ...room, sunday: {...room["sunday"], flag: true } } )
);
因此,我们先映射房间,然后返回具有扩展语法的对象。使用...room
,我们可以保留room
对象之外的sunday
部分。使用sunday: {...room["sunday"], flag: true }
,我们保留sunday
属性中flag
以外的部分。另外,实际上我们不需要复制:
const resultsRooms = [
...this.state.results[0].rooms ];
由于我们不对其进行突变,因此我们使用map
创建了一个新数组。所以,这是最后一个版本:
const rooms = results[0].rooms.map((room, roomIndex) =>
( { ...room, sunday: {...room["sunday"], flag: true } } )
);
这部分还可以,我们不会更改状态,但是如果您在forEach
上使用results
,则会更改原始数据。不要这样
这是一种简洁的方法,也许是一种更清洁的选择,而无需使用forEach
。
const newRooms = results[0].rooms.map( room =>
( { ...room, sunday: {...room["sunday"], flag: true } } )
);
const newItem = { ...results[0], rooms: newRooms };
const newResults = Object.assign([], results, { 0: newItem } );
评论后更新
我在这里使用Object.assign
来替换项目而不改变原始数组。当使用React时(同样如果您更喜欢与React一起使用,这也适用于Redux),我们应该避免改变我们的数据,即我们的状态。因此,当您打算在状态下更改某些内容时,应该以正确的方式进行操作。您的问题实际上表明:“无变异”。这就是为什么我在这里使用Object.assign
的原因。
我可以选择其他方法,例如:
const newResults = results.slice();
newResults[ 0 ] = newItem;
或
const newResults = [ ...results ];
newResults[ 0 ] = newItem;
没关系的仅用于整体替换物品。我这是什么意思slice
和spread syntax
不会创建深层副本,它们只是创建浅层副本。如果您在新创建的数组中更改对象的属性,则原始对象也会发生变化。当我们更改嵌套属性时,这也适用于对象。实际上,原始来源是这里的对象。
这是一个示例数组:
const arr = [
{ id:1, name:"foo" },
{ id:2, name:"bar" },
{ id:3, name:"baz" },
];
以及要更改索引2的示例项(此处为最后一项);
const newItem = { id: 100, name: "change" };
const newArr = [ ...arr ];
arr[ 2 ] = newItem;
可以,因为我们在这里更改了整个对象。让我们看看:
const arr = [
{ id:1, name:"foo" },
{ id:2, name:"bar" },
{ id:3, name:"baz" },
];
const newItem = { id: 100, name: "change" };
const newArr = [ ...arr ];
newArr[ 2 ] = newItem;
console.log("new array", newArr );
console.log( "original array", arr );
原件不变。但是,如果我们这样做:
newArr[ 2 ].id = 100; // ie, we only want to change the id, right?
让我们看看:
const arr = [
{ id:1, name:"foo" },
{ id:2, name:"bar" },
{ id:3, name:"baz" },
];
const newArr = [ ...arr ];
newArr[ 2 ].id = 100;
console.log("new array", newArr );
console.log( "original array", arr );
因此,我们的原始数组也发生了变化。突变!如果您不更改任何此类属性,则可以选择所有三个选项之一。但是,如果您更改属性,则应该考虑一些更好的方法。
const arr = [
{ id:1, name:"foo" },
{ id:2, name:"bar" },
{ id:3, name:"baz" },
];
const newArr = Object.assign( [], arr, { 2: { ...arr[ 2 ], id: 100 } } );
console.log("new array", newArr );
console.log( "original array", arr );
Du! :)也许有更好的方法可以做到这一点:)无论如何,在改变状态时要非常小心。
只有一个对象:
const obj = {
user: {
id: 1,
name: "foo",
}
};
const newObj = { ...obj }
newObj.user.id = 1000
console.log( "new object", newObj );
console.log( "original object", obj );
好的,这足以说明问题了:)
谢谢您的回答。我有点困惑,我应该设定 状态如下:this.setState({results:newResults});
是的
如果我想更改所有结果数组房间的状态怎么办 结果[0],结果[1],结果[2] .....
来吧,这里有个很棒的工具:) map
const newResults = results.map( item => {
const newRooms = item.rooms.map( room =>
( { ...room, sunday: {...room["sunday"], flag: true } } )
);
const newItem = { ...item, rooms: newRooms };
return newItem;
})
首先,我们映射results
,对于每个项目,我们映射rooms
并更改数据,返回新项目。所以最后,我们得到了一个新数组,其中所有项目均发生了变化,但又没有任何突变。
我建议稍微使用map
,filter
和也许reduce
方法。另外,还希望寻找spread syntax
或您更喜欢Object.assign
。