我有一个操作,当用户尝试登录并且请求仍处于暂挂状态时调度:
function signinRequestReducer(state, action) {
if (action.type === "SIGNIN_REQUEST") {
state = {signingIn: true};
}
return state;
}
然而,如果启动两次会发生什么(由于代码中的其他地方的错误)。如果reducer忽略第二个动作(并保持纯函数),它应该抛出一个错误(并且不再是一个纯函数),还是别的什么?
function signinRequestReducer(state, action) {
if (action.type === "SIGNIN_REQUEST") {
if (state.signingIn) {
// Option 1
return state;
// Option 2
raise new Error("Can not sign in whilst pending previous attempt.");
// Option 3 ... ?
}
state = {signingIn: true};
}
return state;
}
** 修改 **
目前我正在记录错误。
if (action.type === "SIGNIN_REQUEST") {
if (state.signingIn) {
console.error("Can not sign in whilst pending previous attempt.");
// return state; // only return early if it's really not possible to set the new state.
}
...
这不是一个纯函数,但确实允许:
** 编辑2 **
答案 0 :(得分:2)
首先,在这个例子中,让动作发生两次是否有任何伤害?所有这一切都将signingIn
再次设置为true
,这似乎不是最糟糕的事情。
肯定有些时候你不希望重复行动,所以我会继续下面的答案。
当涉及到重复操作时,我更愿意完全阻止调度操作,而不是在reducer中吞下它。
一般来说,我们希望保护这种行为的异步操作,例如api请求,这种方法不仅可以阻止状态多次更新,还可以阻止实际工作发生两次。使用异步中间件(例如redux-thunk或redux-saga)可以提供一些有用的工具来执行此操作。
在redux-thunk中,thunk有第二个参数,允许你检查访问状态。如果,在您的示例中,您在异步请求开始之前的状态中设置了一个标志,则可以在第二个操作启动事件之前使用to来避开thunk。
const signIn = (/* your parameters here */) => (dispatch, getState) => {
if (getState().path.to.signingIn) {
// console.error or throw Error here if you prefer
return;
}
dispatch({ type: 'SIGNIN_REQUEST' });
// do sign in
}
注意: redux-thunk也可以这种方式用于同步操作(实际上,这就是我在我的示例中所示)。
我对redux-saga不太熟悉,但似乎有pretty standard pattern for only taking the first action。
答案 1 :(得分:0)
记录错误。
if (action.type === "SIGNIN_REQUEST") {
if (state.signingIn) {
console.error("Can not sign in whilst pending previous attempt.");
// return state; // only return early if it's really not possible to set the new state.
}
...
这不是纯粹的功能,但确实允许:
Dan Abramov建议抛出错误。