React+Redux新增分类报categories not iterable,Reducer返回两次第二次为undefined
问题修复方案
错误原因梳理
你遇到的两个错误本质上都来源于getNewCategory工具函数的逻辑错误、字段拼写错误,以及reducer的逻辑疏漏:
categories not iterable报错是因为代码遍历了不存在的字段,得到undefined后执行for of遍历触发异常- Reducer执行两次返回、第二次值为undefined是因为
getNewCategory递归参数错误导致返回值异常,最终赋值给categories的是undefined,后续组件遍历的时候就会触发报错
具体修改点
1. 修复categories.reducer.js中的getNewCategory函数
原函数存在字段拼写错误、递归逻辑错误,且未处理顶级分类的新增场景,修改后代码如下:
const getNewCategory = (parentId, categories, newCategory) => { // 处理顶级分类:parentId为空/undefined时直接追加到根分类数组 if (!parentId) { return [...categories, newCategory]; } return categories.map(cat => { // 匹配到父分类,将新分类追加到children中 if (cat._id == parentId) { return { ...cat, children: cat.children ? [...cat.children, newCategory] : [newCategory] }; } // 存在子分类则递归遍历子分类 if (cat.children && cat.children.length > 0) { return { ...cat, children: getNewCategory(parentId, cat.children, newCategory) }; } // 不匹配也没有子分类直接返回原分类 return cat; }); };
2. 修正reducer逻辑
你遗漏了GET_CATEGORY_REQUEST的处理逻辑,同时ADD_CATEGORY_FAILURE场景错误地重置了整个state,并且缺少default分支,修改后代码如下:
export default (state = initState, action) => { switch (action.type) { case categoryConstants.GET_CATEGORY_REQUEST: return { ...state, loading: true }; case categoryConstants.GET_CATEGORY_SUCCESS: return { ...state, loading: false, categories: action.payload.categoryList, error: null }; case categoryConstants.GET_CATEGORY_FAILURE: return { ...state, loading: false, error: action.payload.error }; case categoryConstants.ADD_CATEGORY_REQUEST: return { ...state, loading: true }; case categoryConstants.ADD_CATEGORY_SUCCESS: const category = action.payload.category; const updatedCategories = getNewCategory( category.parentId, state.categories, category ); return { ...state, loading: false, categories: updatedCategories, error: null }; case categoryConstants.ADD_CATEGORY_FAILURE: return { ...state, loading: false, error: action.error }; // 必须添加default分支返回原state,否则其他action触发时会丢失state数据 default: return state; } };
3. 可选优化:调整弹窗关闭逻辑
原sendData函数中调用异步新增接口后立刻关闭弹窗,会出现新增失败但弹窗已关闭的问题,可在组件中监听state的loading状态,等loading变为false且无报错时再关闭弹窗。
内容的提问来源于stack exchange,提问作者Ammar Iqbal
相关产品推荐
相关产品推荐

