如何将对象数组最后两项合并为单条数据在表格列展示并解决报错
报错原因分析
- 第一个报错
Uncaught (in promise) TypeError: Invalid attempt to spread non-iterable instance的直接原因是调用merge_last_two_2(row)时,传入的row不是数组类型,建议先做数组类型校验再执行合并逻辑,避免非数组值传入触发扩展运算符报错。 - 第二个隐藏逻辑bug:你写的合并函数中,拼接后的路径存在
name字段里,但后续渲染代码全部读取row.path属性,会导致合并后的项匹配不到任何判断条件,渲染异常。
优化后可运行的实现方案
render() { // 数组校验:只有row是数组且长度≥2时才执行合并,否则直接返回原数据避免报错 const processedRows = Array.isArray(row) && row.length >= 2 ? (() => { // 取除最后两项外的所有前置元素 const frontItems = row.slice(0, -2); // 取最后两个手机号相关的项 const [areaCodeItem, phoneNumItem] = row.slice(-2); // 合并项和原数组项保持属性名一致,直接用path字段 const mergedItem = { path: `${areaCodeItem.path} + ${phoneNumItem.path}`, value: `${areaCodeItem.value}${phoneNumItem.value}` }; return [...frontItems, mergedItem]; })() : row; // 手机号格式化函数,直接输出703-123-6578格式 const formatPhoneNumber = (val) => { if(!val) return ''; return val.replace(/(\d{3})(\d{3})(\d{4})/, '$1-$2-$3'); }; return ( <tr> {processedRows.map((row, x) => { const path = row.path.includes("index") ? row.path.replace("index", i) : row.path; if (row.path.includes("CHK_OUT_TYPE.value")) { return <Radio key={x} name={x} onClick={() => this.getRadioBtnData(i)} /> } else { return ( <Table.Cell>{ row.path.includes("SSN.value") ? formatSSN(_.get(state, path, "")) : row.path === 'PRI_PHN_AREA_CD + PRI_PHN_NR' ? formatPhoneNumber(_.get(state, path, "")) : _.get(state, path, "") }</Table.Cell> ) } })} </tr> ) }
核心优化点
- 新增数组类型、长度校验,从根源避免扩展运算符、pop等操作在非合法输入下的报错
- 合并逻辑改用slice拆分前后段,不需要操作拷贝数组的pop/push,逻辑更直观,也不会出现pop顺序搞混的问题
- 合并后的项和原数组项属性名保持一致,不需要修改原有渲染判断逻辑
- 手机号格式化直接匹配3+3+4的数字规则,输出符合需求的带横杠格式
内容的提问来源于stack exchange,提问作者Shaun
相关产品推荐
相关产品推荐

