我的状态可能看起来像这样:
[
0: {
"id": "8e9x23x2wto",
"name": "test-player",
"currentFrame": 1,
"rolls": {
"1": [1,3],
"2": [1,6],
"3": [1,6],
"4": [3,8],
"5": [4,5],
"6": [7,6],
"7": [8,1],
"8": [5,2],
"9": [2,1],
"10": [1,1]
},
"totalWins": 0
}
]
我正在清除rolls
对象并像这样重置currentFrame
:
case RESET_GAME:
return {
...state,
players: state.players.map((player) => {
return {
...player,
currentFrame: 1,
rolls: Object.assign(player.rolls, Object.values(player.rolls).map(() => []))
}
}),
}
但是,有时rolls
中的随机数组不会被清除-可能是第二个,可能是最后一个...我不知道如何。
是否有其他方法可以清除rolls
,使其仅由空数组组成,或者有人对为什么会发生这种情况有解释?
任何输入都非常感谢!
答案 0 :(得分:2)
我不确定100%,但是从这个角度看,我敢打赌这些问题是由于player.rolls
对象的突变而不是创建它的干净版本而引起的。
现在,带有对象的代码正在创建一个新对象,并用旧对象中的键/值填充该新对象。这样可以保持对象的不变性,而不是使原始对象变异。 React / Redux往往对可变对象不好。
可变示例:
const x = {};
Object.assign(x, {'a': 1, 'b': 2});
// x is now {'a': 1, 'b': 2}
在此示例中,我们采用x并将其变异。请注意,这里我们也将const
与x一起使用有点棘手,这仅意味着我们无法重新分配x所代表的“指针”,但仍可以更改该指针所指向的值。这么说
const x = {};
x = 2; // Will not work
不可变的示例:
var x = {};
x = {...x, ...{'a': 1, 'b': 2}}; // assign x to a new object populated by the previous x and the new stuff
在这种情况下,我们没有突变x对象,而是将x分配给了一个新对象,该对象使用旧x对象中的键/值和我们想在其中包含的新对象键/值来填充(但在这种情况下,则不必要,因为x最初没有任何键/值。
return { // not mutating
...state,
players: state.players.map((player) => { // not mutating
return { // not mutating
...player,
currentFrame: 1,
rolls: Object.assign( // mutating player.rolls rather than making a new rolls object.
player.rolls,
Object.values(player.rolls).map(() => [])
)
}
}),
}
我建议您做类似...
return {
...state,
players: state.players.map((player) => {
return {
...player,
currentFrame: 1,
rolls: []
}
}),
}
这更简单,更干净,而且正如您所说,您只是清除了整个rolls
键...除非我误解了?
另请参阅Object.assign's MDN page,其中指出 目标对象-应用于源属性的对象,在修改后会返回。 (以粗体显示)。
我想不出很多情况,您想使用Object.assign来使用散布运算符({...{'a': 1}, ...{'b': 2}}
)。
再来看一遍,我意识到您想重新制作rolls
对象中的10个条目,而不是完全丢失它们。
我认为更好的解决方案是只制作一个包含空条目的新鲜对象。即
return {
...state,
players: state.players.map((player) => {
return {
...player,
currentFrame: 1,
rolls: {
"1": [0,0],
"2": [0,0],
"3": [0,0],
"4": [0,0],
"5": [0,0],
"6": [0,0],
"7": [0,0],
"8": [0,0],
"9": [0,0],
"10": [0,0]
}
}
}),
}
我不确定为什么要在列表上使用带有数字键的对象,但是可以。
答案 1 :(得分:2)
常见的是:
const initialState = {...}
createStore(myReducer, initialState)
的初始状态case RESET_GAME: return initialState
答案 2 :(得分:1)
您可以使用Object.fromEntries
players: state.players.map((player) => {
return {
...player,
currentFrame: 1,
rolls: Object.fromEntries( Object.keys(player.rolls).map((key)=>[key,[]]))
}
}
let player = {
rolls: {
"1": [1, 3],
"2": [1, 6],
"3": [1, 6],
"4": [3, 8],
"5": [4, 5],
"6": [7, 6],
"7": [8, 1],
"8": [5, 2],
"9": [2, 1],
"10": [1, 1]
}
}
console.log(Object.fromEntries( Object.keys(player.rolls).map((key)=>[key,[]])))