ngrx开发遇TypeError: action.payload不可迭代报错,无法使用扩展运算符
NgRx 扩展运算符报错
action.payload is not iterable 解决方案 根因定位
报错本质是传给GetImages action的payload不是可迭代的数组类型,和reducer中的扩展运算符写法无关。
问题出在images.effect.ts的错误转换:
- HTTP接口返回的
Image[]本身是可迭代的标准数组 - 你在后续map中写的
return { ...images },会把数组展开为以索引为键的普通对象(例如数组[{id:1}, {id:2}]会被转成{0: {id:1}, 1: {id:2}}),彻底失去数组的可迭代特性 - 普通对象默认没有实现迭代器接口,因此reducer中执行
[...action.payload]时就会抛出不可迭代错误 - 你之前测试直接赋值
action.payload能正常取到数据,只是因为对象的键和数组索引规则一致,模板渲染时碰巧能匹配到对应值,实际类型已经不符合定义要求。
补充:开启TypeScript严格类型检查的话,这里的对象/数组类型不匹配问题会在编译阶段被拦截,不会等到运行时才暴露。
修复代码
1. 修正effect中的错误转换逻辑
删除多余的对象展开操作,直接返回接口原始数组,同时加兜底空值处理:
// 修改后的 fetchImages$ 完整代码 fetchImages$ = createEffect( () => this.actions$.pipe( ofType(ImagesActions.FETCH_IMAGES), switchMap(() => this.http.post<Image[]>(this.globalUrl + "/admin/image")), // 直接传递接口返回的数组,删除错误的对象转换逻辑 map((images) => new ImagesActions.GetImages(images ?? [])) ) );
2. (可选)需要处理数组数据时的正确写法
如果要对返回的图片数据做加工,要始终返回数组类型,不要转成对象:
// 示例:给每个图片补充默认字段 map((images) => images.map(img => ({ ...img, isLoaded: false }))), map((processedImages) => new ImagesActions.GetImages(processedImages))
3. reducer层兜底优化
可以在reducer中增加类型判断,避免异常payload导致运行时崩溃:
// images.reducer.ts 中 GET_IMAGES 分支修改 case ImagesActions.GET_IMAGES: return { ...state, images: Array.isArray(action.payload) ? [...action.payload] : [], };
内容的提问来源于stack exchange,提问作者Hyunsu Kim
相关产品推荐
相关产品推荐

