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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.25 11:52:17