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

如何通过NgRx Reducer更新布尔类型状态属性值

NgRx Reducer 状态更新问题修复方案

你的代码存在4个核心问题,会导致状态无法正常更新:

  • Action payload设计冗余:开关导航是固定修改isNavOpen为true/false的操作,不需要传入整个GlobalModel作为参数,多余的传参反而容易引发状态覆盖错误。
  • 初始状态不符合类型定义:你将entities初始值设为null,状态初始化时navigation字段不存在,首次更新极易触发空值报错。
  • Reducer更新逻辑错误:直接用传入的payload整体替换entities,没有做逐层的不可变对象拷贝,也没有匹配到对应action时的默认返回分支,未命中的action会直接把状态置为undefined。
  • 未确认reducer注册状态:写完reducer如果没有在NgRx Store中注册,状态不会被框架托管,自然无法正常更新。

修正后的Action代码(global.actions.ts)

去掉不需要的payload定义,动作本身就代表固定的状态变更意图:

import { Action } from "@ngrx/store";

export enum Types {
  NAV_OPEN = '[Global] NAV: open',
  NAV_CLOSE = '[Global] NAV: close',
}

export class NavOpen implements Action {
  readonly type = Types.NAV_OPEN;
}

export class NavClose implements Action {
  readonly type = Types.NAV_CLOSE;
}

export type All = NavOpen |  NavClose;

修正后的Reducer代码

补全合法的初始状态,逐层做不可变更新,添加默认返回分支:

import { GlobalModel } from "./global.models";
import * as fromAction from './global.actions';

export interface GlobalState {
  entities: GlobalModel;
}

const initialState: GlobalState = {
  entities: {
    navigation: {
      isNavOpen: false
    }
  },
}

export function reducer (
  state = initialState,
  action: fromAction.All
) : GlobalState {

  switch(action.type) {
    case fromAction.Types.NAV_OPEN: {
      return {
        ...state,
        entities: {
          ...state.entities,
          navigation: {
            ...state.entities.navigation,
            isNavOpen: true
          }
        }
      }
    }

    case fromAction.Types.NAV_CLOSE: {
      return {
        ...state,
        entities: {
          ...state.entities,
          navigation: {
            ...state.entities.navigation,
            isNavOpen: false
          }
        }
      }
    }

    default:
      return state
  }
}

检查Store注册配置

确保你已经在对应模块中注册了该reducer:

  • 根模块中使用StoreModule.forRoot({ global: reducer })导入注册
  • 如果是特性模块的状态,使用StoreModule.forFeature('global', reducer)注册

组件中调用示例:

import { Store } from '@ngrx/store';
import * as GlobalActions from './global.actions';
import { GlobalState } from './global.reducer';

constructor(private store: Store<{ global: GlobalState }>) {}

// 触发打开导航
openNav() {
  this.store.dispatch(new GlobalActions.NavOpen());
}

// 触发关闭导航
closeNav() {
  this.store.dispatch(new GlobalActions.NavClose());
}

// 订阅导航状态
isNavOpen$ = this.store.select(state => state.global.entities.navigation.isNavOpen);

如果你使用NgRx 8+版本,更推荐官方提供的createAction、createReducer函数式写法,能减少大量手动拷贝对象的样板代码,降低不可变更新的出错概率。

内容的提问来源于stack exchange,提问作者orphen92300

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 03:09:19