Redux:异步执行减速器?
Redux: Execute reducers asynchronously?
我正在研究保龄球计分系统,但我很困惑为什么以下系统没有按预期工作。
我的状态可能是这样的:
players: [
{
"id": "f44t0uagdyg",
"name": "test-player",
"currentFrame": 1,
"active": false,
"rolls": {
"0": [2,3],
"1": [1,5],
"2": [],
"3": [],
"4": [],
"5": [],
"6": [],
"7": [],
"8": [],
"9": [],
"10": []
},
"totalWins": 0
},
{
"id": "5gbxlu94zpr",
"name": "test-player-2",
"currentFrame": 1,
"active": false,
"rolls": {
"1": [1,6],
"2": [],
"3": [],
"4": [],
"5": [],
"6": [],
"7": [],
"8": [],
"9": [],
"10": []
},
"totalWins": 0
}
]
现在,每当用户输入新的 roll 时,我都想将其添加到商店中 reducers
(它们按预期工作):
要将卷添加到状态,我执行以下操作:
case ADD_ROLL:
return {
...state,
players: state.players.map((player) => {
if (player.id === action.id) {
return {
...player,
rolls: {
...player.rolls,
[action.frame]: [
...player.rolls[action.frame],
action.roll
]
}
}
}
return player;
})
};
要前进到下一帧(例如,在用户输入 2 次掷骰或掷一次攻击后),我这样做:
case NEXT_FRAME:
return {
...state,
players: state.players.map((player) => {
if (player.id === action.id) {
return {
...player,
currentFrame: player.currentFrame + 1,
}
}
return player;
})
}
在用户点击确认他的输入后,这个 advanceGame
函数被调用以评估游戏是否应该前进到下一帧(如果用户已经滚动了两次):
export const advanceGame = (players, roll) => {
let currentPlayer = 0;
const { currentFrame } = players[currentPlayer];
if (players[currentPlayer].rolls[currentFrame].length === 2) {
store.dispatch(nextFrame(players[currentPlayer].id));
store.dispatch(addRoll(players[currentPlayer].currentFrame, roll, players[currentPlayer].id));
} else {
store.dispatch(addRoll(players[currentPlayer].currentFrame, roll, players[currentPlayer].id));
}
};
我希望发生的情况是,如果用户已经滚动了两次,store.dispatch(nextFrame)
将 currentFrame
更新为下一个,然后 然后 将分数添加到适当的帧。但是,目前帧仅在进行了 3 次滚动并且 3 项在 roll
数组中后才会前进。
如何确保 ADD_ROLL
仅在 NEXT_FRAME
具有 'finished' 之后执行?
我已经盯着这个看了很长时间了,如果我的问题太冗长,我深表歉意。很高兴清理它并感谢任何帮助!
我不知道这是否正是您要找的,但我认为减速器总是同步的。
也许您可以尝试将操作设为异步。
Redux-thunk 是为 https://github.com/reduxjs/redux-thunk
制作的
例如,您可以调度一个执行 api 调用的操作,第二个操作仅在 api 已返回他的响应时才调用。
你应该找到需要时间执行的代码并将其替换在 thunk 中,并且只调用 reducer 来更新你的状态。
我正在研究保龄球计分系统,但我很困惑为什么以下系统没有按预期工作。
我的状态可能是这样的:
players: [
{
"id": "f44t0uagdyg",
"name": "test-player",
"currentFrame": 1,
"active": false,
"rolls": {
"0": [2,3],
"1": [1,5],
"2": [],
"3": [],
"4": [],
"5": [],
"6": [],
"7": [],
"8": [],
"9": [],
"10": []
},
"totalWins": 0
},
{
"id": "5gbxlu94zpr",
"name": "test-player-2",
"currentFrame": 1,
"active": false,
"rolls": {
"1": [1,6],
"2": [],
"3": [],
"4": [],
"5": [],
"6": [],
"7": [],
"8": [],
"9": [],
"10": []
},
"totalWins": 0
}
]
现在,每当用户输入新的 roll 时,我都想将其添加到商店中 reducers
(它们按预期工作):
要将卷添加到状态,我执行以下操作:
case ADD_ROLL:
return {
...state,
players: state.players.map((player) => {
if (player.id === action.id) {
return {
...player,
rolls: {
...player.rolls,
[action.frame]: [
...player.rolls[action.frame],
action.roll
]
}
}
}
return player;
})
};
要前进到下一帧(例如,在用户输入 2 次掷骰或掷一次攻击后),我这样做:
case NEXT_FRAME:
return {
...state,
players: state.players.map((player) => {
if (player.id === action.id) {
return {
...player,
currentFrame: player.currentFrame + 1,
}
}
return player;
})
}
在用户点击确认他的输入后,这个 advanceGame
函数被调用以评估游戏是否应该前进到下一帧(如果用户已经滚动了两次):
export const advanceGame = (players, roll) => {
let currentPlayer = 0;
const { currentFrame } = players[currentPlayer];
if (players[currentPlayer].rolls[currentFrame].length === 2) {
store.dispatch(nextFrame(players[currentPlayer].id));
store.dispatch(addRoll(players[currentPlayer].currentFrame, roll, players[currentPlayer].id));
} else {
store.dispatch(addRoll(players[currentPlayer].currentFrame, roll, players[currentPlayer].id));
}
};
我希望发生的情况是,如果用户已经滚动了两次,store.dispatch(nextFrame)
将 currentFrame
更新为下一个,然后 然后 将分数添加到适当的帧。但是,目前帧仅在进行了 3 次滚动并且 3 项在 roll
数组中后才会前进。
如何确保 ADD_ROLL
仅在 NEXT_FRAME
具有 'finished' 之后执行?
我已经盯着这个看了很长时间了,如果我的问题太冗长,我深表歉意。很高兴清理它并感谢任何帮助!
我不知道这是否正是您要找的,但我认为减速器总是同步的。
也许您可以尝试将操作设为异步。 Redux-thunk 是为 https://github.com/reduxjs/redux-thunk
制作的例如,您可以调度一个执行 api 调用的操作,第二个操作仅在 api 已返回他的响应时才调用。
你应该找到需要时间执行的代码并将其替换在 thunk 中,并且只调用 reducer 来更新你的状态。