如果我以这种方式为异步操作设计Reducer,我会遇到什么问题?

时间:2017-04-05 14:25:05

标签: redux react-redux

我在创建前端应用程序方面经验很少,并希望在使用Redux时为自己建立一些约定。

目前我的异步操作的reducers如下所示:

const initialState = {
    isRunning: false,
    isFinished: false,
    hasError: false,
    response: null
};
export const updatePostReducer = (state = initialState, action=null) => {
    switch (action.type) {
        case UPDATE_POST:
            return {
                isRunning: true,
                isFinished: false,
                hasError: false,
                response: null
            };
        break;

        case UPDATE_POST_SUCCESS:
            return {
                isRunning: false,
                isFinished: true,
                hasError: false,
                response: action.payload
            };
        break;

        case UPDATE_POST_ERROR:
            return {
                isRunning: false,
                isFinished: false,
                hasError: true,
                response: null,
                statusCode: action.statusCode
            };

        case UPDATE_POST_INVALIDATE:
            return initialState;
        break;

        default:
            return state;
    }
};

上述方法没有问题,但我发现“过程阶段”令人困惑。因此,我的想法是将其缩短为:

// IMPORTED FROM SEPARATE FILE
const stage = {
  INITIAL: "INITIAL",
  RUNNING: "RUNNING",
  FINISHED: "FINISHED",
  ERROR: "ERROR"
};

const initialState = {
    stage: stage.INITIAL,
    response: null
};
export const updatePostReducer = (state = initialState, action=null) => {
    switch (action.type) {
        case UPDATE_POST:
            return {
                stage: stage.RUNNING,
                response: null
            };
        case UPDATE_POST_SUCCESS:
            return {
                stage: stage.FINISHED,
                response: action.payload
            };
        case UPDATE_POST_ERROR:
            return {
                stage: stage.ERROR,
                response: null,
                statusCode: action.statusCode
            };
        case UPDATE_POST_INVALIDATE:
            return initialState;

        default:
            return state;
    }
};

我使用后一种方法看到了两个优点:

  1. 它更干净
  2. 可以使用switch()代替肮脏的if-elses
  3. 缺点是:

    1. 这需要在任何地方导入阶段.js。
    2. 阶段没有细粒度的控制
    3. 我的问题是:由于阶段没有细粒度的控制,这会在某些情况下引起问题吗?例如,是否有可能需要同时拥有hasError=true, isRunning=true

1 个答案:

答案 0 :(得分:1)

如果不了解应用程序的用例,您提出的问题很难回答。但如果它不是一个非常简单的那个,我会说你迟早会遇到这种简化问题。

我还发现了一些非初始化值的问题,例如statusCode。顺便说一句,其他州没有更新。如果在发生错误时更新了代码,则在成功重试后它仍然是相同的。

我会提出另一种方式,使用combineReducers()更加明确。

以下是:

const isRunningReducer = (state=false, action=null) => {
    switch (action.type) {
        case UPDATE_POST:
            return true;
        case UPDATE_POST_SUCCESS:
            return false;
        case UPDATE_POST_ERROR:
            return false;
        case UPDATE_POST_INVALIDATE:
            return false;
        default:
            return state;
    }
};

const isFinishedReducer = (state=false, action=null) => {
    switch (action.type) {
        case UPDATE_POST:
            return false;
        case UPDATE_POST_SUCCESS:
            return true;
        case UPDATE_POST_ERROR:
            return false;
        case UPDATE_POST_INVALIDATE:
            return false;
        default:
            return state;
    }
};

const hasErrorReducer = (state=false, action=null) => {
    switch (action.type) {
        case UPDATE_POST:
            return false;
        case UPDATE_POST_SUCCESS:
            return false;
        case UPDATE_POST_ERROR:
            return true;
        case UPDATE_POST_INVALIDATE:
            return false;
        default:
            return state;
    }
};

const statusCodeReducer = (state=null, action=null) => {
    switch (action.type) {
        case UPDATE_POST:
            return null;
        case UPDATE_POST_SUCCESS:
            return action.statusCode;
        case UPDATE_POST_ERROR:
            return action.statusCode;
        case UPDATE_POST_INVALIDATE:
            return null;
        default:
            return state;
    }
};

const responseReducer = (state=null, action=null) => {
    switch (action.type) {
        case UPDATE_POST:
            return null;
        case UPDATE_POST_SUCCESS:
            return action.payload;
        case UPDATE_POST_ERROR:
            return null;
        case UPDATE_POST_INVALIDATE:
            return null;
        default:
            return state;
    }
};

export const updatePostReducer = combineReducers({
    isRunningReducer,
    isFinishedReducer,
    hasErrorReducer,
    statusCodeReducer,
    responseReducer,
});

缺点:

  • 更详细
  • 重复

优点:

  • 非常简单易懂的减压器
  • 不易出错
  • 易于扩展
  • 易于编写生成器代码,以便可以导入标准缩减器,如“isRunning”,“isFinished”等。

使用自己的createReducer()方法可以使所有这些更加优雅:Reducing Boilerplate - Generating Reducers

相关问题