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

为何我的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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 07:37:23