Angular中NgRx导出reducer并接入StoreModule.forRoot相关疑问
问题解答
- 问题1:
counterReducer包装函数的作用
这层函数是为了兼容Angular旧版的View Engine AOT编译器。createReducer调用后返回的是一个匿名函数表达式,View Engine的AOT编译逻辑无法识别将这种动态生成的函数直接用在@NgModule元数据的StoreModule.forRoot配置中,会触发编译报错。套一层具名的普通导出函数后,AOT编译器就能正常识别这个reducer引用,完成构建。 - 问题2:
counterReducer是否必需
分场景判断:- 如果你使用Angular 9之前的版本,或者Angular 9-11版本手动开启了View Engine编译器,这个包装函数是必需的,否则AOT构建会失败。
- 如果你使用Angular 9+默认的Ivy编译器,或者使用JIT编译模式,这个函数完全不需要,可以省略。
- 问题3:为什么不直接导出
_counterReducer到模块中使用
就是上述View Engine的编译限制导致的。旧版本Angular生态下直接将_counterReducer传入StoreModule.forRoot,AOT构建阶段会直接抛出无法解析元数据的错误,所以早期的NgRx官方示例都统一加了这层包装来兼容所有编译场景。
你提到的NgRx官方说明完全可以解释以上所有疑问,这段说明就是针对这个写法的历史背景给出的解释。现在Angular 12及以后的版本已经完全移除了View Engine,默认全用Ivy编译器,现在写NgRx reducer的时候可以直接简化成如下写法,不需要额外包装:
// 新版本简化写法 export const counterReducer = createReducer( initialState, on(increment, (state) => state + 1), on(decrement, (state) => state - 1), on(reset, (state) => 0) );
内容的提问来源于stack exchange,提问作者walexy
相关产品推荐
相关产品推荐

