Angular+NgRx图片上传后重定向失败,报Effect无效动作错误
问题分析
报错的核心原因:
- NgRx Effect 默认会把管道返回的所有值当作 Action 派发,但你的代码里
map函数返回的是router.navigate()的结果(一个 Promise),不是合法的 NgRx Action,因此触发了「无效动作」错误。 - 代码里
data[data.length].post_id存在索引越界问题,数组最后一项的索引应为data.length - 1,这会导致无法获取正确的 post_id,进而引发导航失败。
修复步骤
禁用 Effect 自动派发动作
这个 Effect 仅用于执行导航这类副作用,不需要派发新 Action,所以要在createEffect中添加{ dispatch: false }配置。用
tap替代map执行副作用map用于转换流的值为 Action,而tap专门用来执行派发动作、导航这类不改变流的副作用,避免 Effect 尝试派发无效值。修正数组索引错误
将data[data.length].post_id改为data[data.length - 1].post_id,解决索引越界问题。完善错误处理逻辑
原catchError直接返回err会导致 Effect 派发错误对象作为动作,应返回一个失败 Action(比如uploadFileFailure)。
修复后的代码
uploadFile$ = createEffect(() => { return this.actions$.pipe( ofType(uploadFile), switchMap((action) => { return this.createRequestService.uploadFile(action.files, action.post_id).pipe( takeUntil( this.actions$.pipe(ofType(UPLOAD_CANCEL)) ), tap((data) => { this.store$.dispatch(uploadFileSuccess({ image: data })); // 修正索引后执行导航 this.router.navigate([`/requests/post/${data[data.length - 1].post_id}`]); }), catchError((err) => { // 返回失败动作,避免派发无效值 return of(uploadFileFailure({ error: err })); }) ); }) ); }, { dispatch: false }); // 关键配置:禁用自动派发动作
额外说明
如果需要在导航完成后执行后续逻辑,可以把导航操作放入 switchMap 中(router.navigate 返回的 Promise 可转为 Observable),但依然要保留 { dispatch: false } 配置:
switchMap((data) => { this.store$.dispatch(uploadFileSuccess({ image: data })); return from(this.router.navigate([`/requests/post/${data[data.length - 1].post_id}`])); })
内容的提问来源于stack exchange,提问作者user
相关产品推荐
相关产品推荐

