为何NgRx Platform/Effects会触发未派发的Action?
看起来你遇到的核心问题是:GetUsersSuccess(你提到的GET_USER_SUCCESS应该是笔误,代码里是复数形式)仅在编辑初始加载时从服务器获取的用户时触发,其他场景下无法触发。我们从你提供的Effect代码入手,一步步拆解问题:
先明确当前的触发逻辑
从你贴的Effect代码来看,GetUsersSuccess的派发链路是:
// 触发链路: store.dispatch(new GetUsers()) → Effect监听GET_USERS action → 调用service.getUsers()请求服务器 → 请求成功后派发GetUsersSuccess(users)
所以GetUsersSuccess的触发完全依赖于GET_USERS这个action被dispatch。你观察到的“仅初始加载编辑用户时触发”,说明只有在初始加载编辑页面时,代码里执行了store.dispatch(new GetUsers()),其他场景(比如编辑刚创建的新用户)没有触发这个action。
具体排查与修复步骤
1. 确认GET_USERS的触发时机
- 检查编辑页面的初始化逻辑(比如
ngOnInit方法),应该能找到类似this.store.dispatch(new GetUsers())的代码——这就是初始加载时GetUsersSuccess被触发的原因。 - 检查新增用户后跳转到编辑页面的逻辑:跳转前/后是否也执行了
store.dispatch(new GetUsers())?如果没有,那自然不会触发GetUsersSuccess。
2. 完善更新用户后的数据流(针对编辑新创建用户的场景)
你贴的更新用户Effect代码没写完,推测大概是处理UPDATE_USER action的逻辑。如果希望编辑新创建的用户后也能触发用户数据的刷新(从而触发GetUsersSuccess),可以在更新成功后派发GET_USERS action,保持数据流的一致性:
// 补全后的更新用户Effect示例 this.updateUser = this.actions$.pipe( ofType(UPDATE_USER), // 假设UPDATE_USER是更新用户的action类型 switchMap((action) => this.service.updateUser(action.payload) .pipe( map(() => { // 更新成功后,触发获取用户列表的action,从而触发GetUsersSuccess return new GetUsers(); }), catchError(error => of(new UpdateUserFail(error))) ) ) );
如果只需要刷新单个用户的数据,也可以单独实现一个GET_USER(单个用户)的Effect,更新成功后派发GET_USER action,请求单个用户数据后派发GetUserSuccess(注意和列表的GetUsersSuccess区分开,避免命名混淆)。
3. 检查Action命名的一致性
你提到的是GET_USER_SUCCESS,但代码里是GetUsersSuccess(复数形式),要确保Action的type常量和类完全匹配,比如:
// 确认Action类型定义的一致性 export const GET_USERS = '[User] Get Users'; export const GET_USERS_SUCCESS = '[User] Get Users Success'; // 注意复数 export class GetUsers implements Action { readonly type = GET_USERS; } export class GetUsersSuccess implements Action { readonly type = GET_USERS_SUCCESS; constructor(public payload: User[]) {} }
拼写错误(单复数、大小写)是导致Action无法被正确监听/派发的常见原因。
总结
GetUsersSuccess的触发完全绑定在GET_USERS action的dispatch上,你需要确保在所有需要刷新用户数据的场景(比如编辑新创建的用户后)都dispatch这个action,同时检查Action命名的一致性,就能解决“仅初始加载时触发”的问题。
内容的提问来源于stack exchange,提问作者Akshay Golash

