Angular项目使用NgRX时reducer返回undefined值问题求助
问题原因
store.dispatch()本身无返回值,该方法仅负责将动作分发到Store触发状态流转,设计上就不会直接返回当前状态,所以打印结果为undefined是正常表现- NgRX状态是响应式数据流,不能同步获取,需要通过订阅Store的状态流来拿到最新的状态值
- 你当前的
getReceipts动作对应的reducer处理逻辑是直接返回初始状态,这个动作本身不修改状态的话,Store初始化完成后就已经加载了initialState,不需要主动触发该动作也能拿到默认值
解决方法
步骤1:完善状态类型定义(推荐,避免类型错误)
在file-state.reducer.ts中新增类型定义:
// file-state.reducer.ts export interface Receipt { merchant_name: string; } // 定义全局State接口,方便Store注入时做类型约束 export interface AppState { fileReducer: Receipt; } const initialState: Receipt = { merchant_name: 'default' } // 原有reducer逻辑保持不变 export const fileReducer = createReducer( initialState, on(ReceiptActions.getReceipts, state => initialState) )
步骤2:修改组件代码,通过订阅获取状态
// view-files.component.ts import { Store, select } from '@ngrx/store'; import { getReceipts } from 'src/app/state/file-state/file-state.actions'; import { AppState, Receipt } from 'src/app/state/file-state/file-state.reducer'; import { Observable } from 'rxjs'; export class ViewFilesComponent { receipt$: Observable<Receipt>; constructor(private store: Store<AppState>) { // 选择对应reducer的状态流 this.receipt$ = this.store.pipe(select('fileReducer')); // 订阅状态拿到结果 this.receipt$.subscribe(currentState => { console.log(currentState); // 输出 {merchant_name: 'default'} }) // 若确实需要触发getReceipts动作再保留本行,否则可以删除,初始化就有默认值 this.store.dispatch(getReceipts()); } }
额外提示
如果是在模板中使用状态,推荐直接用Angular的async管道自动订阅和销毁,不需要手动调用subscribe,避免内存泄漏:
<!-- view-files.component.html 示例 --> <div>商家名称:{{ (receipt$ | async)?.merchant_name }}</div>
内容的提问来源于stack exchange,提问作者Peter Boomsma
相关产品推荐
相关产品推荐

