Angular 17 + NgRx子集选择器报错:无法读取undefined的push属性
问题描述
我正在使用Angular 17搭配NgRx进行开发,现有如下选择器可正常工作:
export const getPhotoState = createFeatureSelector<ProductResponse>('selectedPhotos'); export const selectPhotos = createSelector(getPhotoState, (state: ProductResponse) => { return state.results }); export const PhotoCount = createSelector(getPhotoState, (state: ProductResponse) => { return state.item_Count });
由于仅需从已返回的数据中获取子集,我不想编写新的Effect/Reducer去请求服务器。为此我编写了如下代码:
export const XboxPhotos = createSelector(selectPhotos, (reducedPhotos) => { return xboxPhotos('xbox', reducedPhotos) }) function xboxPhotos(key: string, array: any) { return array.reduce((all: Product[], current: Product) => { if (current.platform == key) { all.push(current); } }, []) as Product[] }
但我遇到了错误:
无法读取未定义的属性(读取'push')
注:reducedPhotos的类型为Product[]。请问该如何解决此问题?
解决方案
错误根源在于reduce函数的回调没有返回累加器all。reduce要求每次迭代都必须返回累加器,否则下一次迭代时all会变成undefined,调用push就会触发报错。
修复reduce写法
修改xboxPhotos函数,确保回调末尾返回累加器:
function xboxPhotos(key: string, array: Product[]) { return array.reduce((all: Product[], current: Product) => { if (current.platform === key) { all.push(current); } // 必须返回累加器,保证迭代正常进行 return all; }, []); }
更简洁的替代方案
其实可以直接用filter替代reduce,逻辑更直观且代码更简洁,完全满足你从现有数据取子集的需求:
export const XboxPhotos = createSelector(selectPhotos, (photos) => photos.filter(photo => photo.platform === 'xbox') );
内容的提问来源于stack exchange,提问作者bilpor
相关产品推荐
相关产品推荐

