React应用构建部署后过滤功能报错问题排查
React生产环境过滤功能触发「undefined不可迭代」错误
错误详情
react-dom.production.min.js:106 Uncaught TypeError: undefined is not iterable (cannot read property Symbol(Symbol.iterator)) at _ (iterableToArray.js:2:40) at x (toConsumableArray.js:6:36) at setFilters (gallerySlice.js:92:8) at createReducer.ts:294:20 at produce (immerClass.ts:94:14) at createReducer.ts:293:18 at Array.reduce (<anonymous>) at c (createReducer.ts:260:25) at reducer (createSlice.ts:372:14) at redux.js:560:29
关键现象
仅在构建部署后的生产版本中出现该错误,本地开发环境无异常。
功能实现背景
过滤功能基于两个react-select组件实现,状态由Redux Toolkit(RTK)切片管理,核心代码如下:
RTK切片核心逻辑
setFilters: (state, action) => { const { kategorije, tagovi } = action.payload; console.log('kategorije:', kategorije); console.log('tagovi:', tagovi); state.selectedFilters = { kategorije: Array.isArray(kategorije) ? kategorije.filter(Boolean) : [], tagovi: Array.isArray(tagovi) ? tagovi.filter(Boolean) : [], }; }, ... export const selectFilteredPhotos = state => { const { kategorije, tagovi } = state.gallery.selectedFilters || {}; const allPhotos = state.gallery.photos; if (!kategorije && !tagovi) { return allPhotos; } return allPhotos.filter(photo => { const kategorijaMatches = !kategorije || kategorije.length === 0 || kategorije.every(filter => photo.kategorija && photo.kategorija.includes(filter)); const tagoviIncluded = !tagovi || tagovi.length === 0 || tagovi.every(filter => photo.tagovi && photo.tagovi.includes(filter)); return kategorijaMatches && tagoviIncluded; }); };
问题分析
错误栈指向toConsumableArray.js,说明代码尝试将非可迭代对象转为数组。结合生产环境才出现的现象,大概率是以下原因:
- react-select参数异常:生产环境下,react-select组件传递给
setFilters的kategorije或tagovi不是数组(比如单个值、undefined)——可能是isMulti属性未正确设置,或组件状态在生产优化后出现异常。 - 构建优化导致的参数解构问题:生产环境的代码压缩/混淆可能导致
action.payload未被正确解构,比如action.payload本身为undefined时,kategorije和tagovi会直接是undefined,后续若有隐式迭代操作(比如扩展运算符)就会触发错误。 - 状态初始化不完整:
selectedFilters初始状态若未明确设置kategorije和tagovi为空数组,可能在首次渲染时出现解构异常。
修复方案
1. 强化参数校验与兜底
修改setFilters逻辑,提前对action.payload及属性兜底,避免undefined流入后续逻辑:
setFilters: (state, action) => { // 先对payload和属性做兜底处理 const { kategorije = [], tagovi = [] } = action.payload || {}; state.selectedFilters = { kategorije: Array.isArray(kategorije) ? kategorije.filter(Boolean) : [], tagovi: Array.isArray(tagovi) ? tagovi.filter(Boolean) : [], }; },
2. 确认react-select配置
检查两个过滤组件的isMulti属性是否设置为true,确保选中值始终以数组形式返回:
<Select isMulti={true} // 其他配置 />
3. 优化选择器判断逻辑
调整选择器中的空值判断,增加兜底并简化逻辑:
export const selectFilteredPhotos = state => { const { kategorije = [], tagovi = [] } = state.gallery.selectedFilters || {}; const allPhotos = state.gallery.photos; if (kategorije.length === 0 && tagovi.length === 0) { return allPhotos; } return allPhotos.filter(photo => { const kategorijaMatches = kategorije.length === 0 || kategorije.every(filter => photo.kategorija?.includes(filter)); const tagoviIncluded = tagovi.length === 0 || tagovi.every(filter => photo.tagovi?.includes(filter)); return kategorijaMatches && tagoviIncluded; }); };
内容的提问来源于stack exchange,提问作者Andrija Vranić
相关产品推荐
相关产品推荐

