Ngrx使用on()语法编写Reducer时如何便捷打印所有传入Action
实现方案
不用修改已有的on()语法编写的Reducer逻辑,有两种零侵入的实现方式,按需选择即可。
方案1:单个Reducer外层包装(和旧switch写法逻辑完全一致)
createReducer()执行后本身会返回标准的Reducer函数,你只需要在导出时包一层普通函数,在函数入口添加日志逻辑即可,原有所有on()的处理代码一行都不用改:
// 原有createReducer逻辑保持不变 const baseReducer = createReducer( initialState, on(ScoreboardPageActions.homeScore, state => ({ ...state, home: state.home + 1 })), on(ScoreboardPageActions.awayScore, state => ({ ...state, away: state.away + 1 })), on(ScoreboardPageActions.resetScore, state => ({ home: 0, away: 0 })), on(ScoreboardPageActions.setScores, (state, { game }) => ({ home: game.home, away: game.away })) ); // 外层包装加日志,和旧版switch写法的入口日志效果完全相同 export function scoreboardReducer(state = initialState, action: ScoreboardAction) { console.log('传入Reducer的Action:', action); return baseReducer(state, action); }
方案2:全局Meta Reducer(适合项目全量Reducer打日志,一次配置全生效)
如果要打印所有模块所有Reducer接收的Action,不用逐个修改Reducer,使用NgRx原生支持的Meta Reducer即可,只需要写一次配置:
- 先编写日志Meta Reducer:
import { ActionReducer } from '@ngrx/store'; import { environment } from 'src/environments/environment'; export function logActionMetaReducer(reducer: ActionReducer<any>): ActionReducer<any> { return (state, action) => { // 仅非生产环境打印日志,避免生产环境控制台冗余 if (!environment.production) { console.log('派发的Action:', action); console.log('当前状态:', state); } return reducer(state, action); }; }
- 在Store模块注册时引入该Meta Reducer:
- 根模块注册:
StoreModule.forRoot(rootReducers, { metaReducers: [logActionMetaReducer] })
- 特性模块注册:
StoreModule.forFeature('scoreboard', scoreboardReducer, { metaReducers: [logActionMetaReducer] })
不要尝试给每个
on()的处理函数单独加日志,项目Action量大时维护成本极高,还容易漏写,上面两种方案都不会侵入现有业务逻辑,成本最低。
内容的提问来源于stack exchange,提问作者Michał Lis
相关产品推荐
相关产品推荐

