如何处理redux reducer

时间:2017-04-27 11:13:55

标签: redux

我有一个操作,当用户尝试登录并且请求仍处于暂挂状态时调度:

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 **

Dan Abramov suggested抛出错误。

2 个答案:

答案 0 :(得分:2)

首先,在这个例子中,让动作发生两次是否有任何伤害?所有这一切都将signingIn再次设置为true,这似乎不是最糟糕的事情。

肯定有些时候你不希望重复行动,所以我会继续下面的答案。

当涉及到重复操作时,我更愿意完全阻止调度操作,而不是在reducer中吞下它。

一般来说,我们希望保护这种行为的异步操作,例如api请求,这种方法不仅可以阻止状态多次更新,还可以阻止实际工作发生两次。使用异步中间件(例如redux-thunkredux-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建议抛出错误。