使用 Redux 如何阻止 reducer 中的 switch 增长?
Posted
技术标签:
【中文标题】使用 Redux 如何阻止 reducer 中的 switch 增长?【英文标题】:Using Redux how do you stop the switch in the reducer growing? 【发布时间】:2018-08-05 08:08:42 【问题描述】:我正在使用 Angular 5 和 ng2-Redux。
我正在使用减速器和开关,但我担心开关会随着我添加更多动作类型而增长。
目前我正在尝试使用红色组合减速器来管理状态和文件的增长:
我目前收到此错误:
未处理的 Promise 拒绝:Reducer "app" 在期间返回未定义 初始化。如果传递给减速器的状态是未定义的,你 必须显式返回初始状态。初始状态可能不是 不明确的。如果你不想为这个 reducer 设置一个值,你可以 使用 null 而不是 undefined。 ;区:;任务:Promise.then ; 值:错误:Reducer“app”在初始化期间返回未定义。 如果传递给减速器的状态未定义,则必须显式 返回初始状态。初始状态可能不是未定义的。如果 您不想为此减速器设置值,可以使用 null 而不是未定义。
似乎 rootReducer 需要返回状态,但我使用的是组合减速器。
我的减速机服务代码:
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
);
【问题讨论】:
你可以在关于这个主题的另一个问题中找到答案。***.com/questions/48950721/… @Ricardo 我目前无法将 rootReducer 连接到 app 模块中的配置,这是一个 combineReducer。见上文 【参考方案1】:您应该将您的 IAppState
拆分为不同的功能状态:
export interface IAppState =
auth: IAuthState;
onboarding: IOnboardingState;
feedback: IFeedbackState;
;
然后您使用来自'redux'
的combineReducers
从所有功能缩减器中构建您的rootReducer
:
export const rootReducer = combineReducers(
auth: authReducer,
onboarding: onboardingReducer,
feedback: feedbackReducer
);
因此,您的功能状态、操作、reducer 和史诗将更小且更易于维护。
您可以在操作名称中添加特定于功能的前缀,以确保它们是唯一的:
export class CounterActions
static INCREMENT: string = '[COUNTER] INCREMENT';
static DECREMENT: string = '[COUNTER] DECREMENT';
static RANDOMIZE: string = '[COUNTER] RANDOMIZE';
更新:您的后续问题
解决方法在错误信息中,仔细阅读:
如果传递给reducer的状态是未定义的,你必须明确 返回初始状态。
需要传入初始状态作为默认值:
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
切片。
【讨论】:
现在如何使用这三个减速器中的哪一个? 您的动作名称必须是唯一的,因为它们仍将通过所有减速器。您可以通过为所有操作添加特定于功能的前缀来实现这一点。 根据您的用例,分形存储可能是您的选择。看看github.com/angular-redux/store/blob/master/articles/… 你能给我看一个上面的动作前缀示例,以便调用特定的减速器 我已经编辑了我的答案 ;-) 由于您的操作的独特性,正确的功能缩减程序将更新您的商店。以上是关于使用 Redux 如何阻止 reducer 中的 switch 增长?的主要内容,如果未能解决你的问题,请参考以下文章
在 Redux 中,如果所有 reducer 在动作触发时都被调用,那么是啥阻止了动作之间可能的命名冲突?
如何在reducer中专门使用redux来获取react-native中的API?
如何使用 redux-toolkit 中的 createSlice 方法在不同的 reducer 函数中使用单个动作类型
如何重用 Redux Toolkit createSlice 函数中的 reducer 逻辑?