使用 Redux 如何阻止 reducer 中的 switch 增长?

Using Redux how do you stop the switch in the reducer growing?

使用 Redux 如何阻止 reducer 中的开关增长?

我正在使用 angular 5 和 ng2-Redux。

我正在使用 reducer 和 switch,但我担心随着我添加更多操作类型,switch 会变大。

目前我正在尝试使用红色联合减速器来管理状态和文件的增长:

我目前收到此错误:

Unhandled Promise rejection: Reducer "app" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined. ; Zone: ; Task: Promise.then ; Value: Error: Reducer "app" returned undefined during initialization. If the state passed to the reducer is undefined, you must explicitly return the initial state. The initial state may not be undefined. If you don't want to set a value for this reducer, you can use null instead of undefined.

似乎 rootReducer 需要 return 状态,但我正在使用联合减速器。

我的 Reducer 服务代码:

import { combineReducers } from 'redux';

export interface IAppState {
    counter?: number;
    user?: Object;
    numberOfMessages?: number;
}

export interface IAction {
    type: string;
    payload?: any;
}

export const INITIAL_APP_STATE: IAppState = {
    counter: 0,
    user: {},
    numberOfMessages: 0
};

export const appReducer = (state: IAppState, action: IAction): IAppState => {
    switch (action.type) {
        case 'INCREMENT':
        return  {
            counter: state.counter + action.payload,
            numberOfMessages: state.numberOfMessages
        };
    }
    return state;
};

export const userReducer = (state: IAppState, action: IAction): IAppState => {
    switch (action.type) {
        case 'DECREMENT':
        return  {
            counter: state.counter,
            numberOfMessages: state.numberOfMessages - action.payload
        };
    }
    return state;
};

export const rootReducer = combineReducers({
  app: appReducer,
  user: userReducer
});

这是我的 redux 设置的模块导出部分(我认为这里有错误????):

export class AppModule {
  constructor(ngRedux: NgRedux<IAppState>) {
    ngRedux.configureStore(rootReducer, INITIAL_APP_STATE);
  }
}

这是我的调度方法:

 public increment(): void {
    this.ngRedux.dispatch({
      type: '[app] INCREMENT',
      payload: 1
    });
  }

 public decrement(): void {
    this.ngRedux.dispatch({
      type: '[user] DECREMENT',
      payload: 2
    });
  }

您应该将 IAppState 分成不同的功能状态:

export interface IAppState = {
  auth: IAuthState;
  onboarding: IOnboardingState;
  feedback: IFeedbackState;
};

然后你使用 'redux' 中的 combineReducers 从所有特征缩减器构建你的 rootReducer:

export const rootReducer = combineReducers({
  auth: authReducer,
  onboarding: onboardingReducer,
  feedback: feedbackReducer
});

您的功能状态、操作、reducer 和 epics 将因此变得更小且更易于维护。

您可以为您的操作名称添加功能特定的前缀以确保它们是唯一的:

export class CounterActions {
  static INCREMENT: string = '[COUNTER] INCREMENT';
  static DECREMENT: string = '[COUNTER] DECREMENT';
  static RANDOMIZE: string = '[COUNTER] RANDOMIZE';

更新:您的 follow-up 问题

解决方法在报错信息中,仔细阅读:

If the state passed to the reducer is undefined, you must explicitly return the initial state.

需要传入初始状态作为默认值:

export const userReducer = (state: IUserState = INITIAL_USER_STATE, action: IAction): IAppState => {
                                   ^^^^^^^^^^^   ^^^^^^^^^^^^^^^^^
    switch (action.type) {
        case 'LOGIN':
        return  {
            userName: action.payload.userName
        };
    }
    return state;
};

此外,userReducer 仅获取传入状态的 IUserState 切片。