为何我的SideEffect触发后提示返回Action无type属性?实际已定义
问题根源&解决方案
我立刻就发现问题所在了!你在Effect的最后一步直接返回了一个动作数组,但NgRx的Effect默认要求返回单个Action对象或者发出Action的Observable流,而不是数组。当你返回数组时,NgRx会把这个数组当成一个“动作”来处理,但数组本身并没有type属性,这就直接触发了「Actions must have a type property」的错误。
修复方案(两种可选)
方案1:用from操作符将数组转为Observable流
修改Effect中最后的map为switchMap,并用rxjs的from操作符把动作数组转换成Observable,这样每个动作会被依次派发:
import { from } from 'rxjs'; // ... 其他导入 @Injectable() export class AuthEffects { @Effect() authSignin = this.actions$ .ofType(AuthActions.TRY_SIGNIN) .map((action: AuthActions.TrySignin) => action.payload) .switchMap(authData => this.httpService.postRequest('/Account/Login', authData)) .switchMap(res => { console.log(res['authToken']); // 用from将数组转为Observable,依次派发每个Action return from([ new AuthActions.Signin(), // 直接实例化你定义好的Action类,更规范 new AuthActions.SetToken(res['authToken']) ]); }); }
方案2:用mergeMap自动展开数组
mergeMap会自动把数组转换成Observable流,写法更简洁:
@Injectable() export class AuthEffects { @Effect() authSignin = this.actions$ .ofType(AuthActions.TRY_SIGNIN) .map((action: AuthActions.TrySignin) => action.payload) .switchMap(authData => this.httpService.postRequest('/Account/Login', authData)) .mergeMap(res => { console.log(res['authToken']); return [ new AuthActions.Signin(), new AuthActions.SetToken(res['authToken']) ]; }); }
额外小建议
你之前用{ type: AuthActions.SIGNIN }这种对象字面量的方式不如直接实例化你已经定义好的Signin和SetToken类,这样不仅更符合NgRx的规范,还能避免手动写错type值的风险——毕竟你已经提前定义好了类型安全的Action类,不用白不用😉
内容的提问来源于stack exchange,提问作者JSON
相关产品推荐
相关产品推荐

