You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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即可,只需要写一次配置:

  1. 先编写日志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);
  };
}
  1. 在Store模块注册时引入该Meta Reducer:
  • 根模块注册:
StoreModule.forRoot(rootReducers, {
  metaReducers: [logActionMetaReducer]
})
  • 特性模块注册:
StoreModule.forFeature('scoreboard', scoreboardReducer, {
  metaReducers: [logActionMetaReducer]
})

不要尝试给每个on()的处理函数单独加日志,项目Action量大时维护成本极高,还容易漏写,上面两种方案都不会侵入现有业务逻辑,成本最低。

内容的提问来源于stack exchange,提问作者Michał Lis

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 22:18:14