React嵌套对象作为props传入组件后遍历渲染报错解决方案
问题场景
拿到的业务数据结构如下:
const data = { type: "footer", company_data: { phone: "123456", email: "hello@site.com", page1: { title: "Terms & Conditions", url: "/terms-conditions/", }, page2: { title: "Privacy Policy", url: "/privacy-policy/", }, }, };
通过以下方式向Footer组件传递props:
<Footer data={data} />
Footer组件初始代码:
export default function Footer({ data }) { return ( <div> {data.type} </div> ); }
初始代码可正常渲染type字段值footer,但尝试使用Object.entries方法遍历数据时触发报错:
Error: Objects are not valid as a React child (found: object with keys {phone, email, page1, page2}). If you meant to render a collection of children, use an array instead.
已知React不支持直接将对象作为子元素渲染,尝试通过Object.entries(data)将对象转为数组后,因数组内仍保留嵌套对象结构,依旧触发相同报错。需要在保留原有键值结构的前提下,得到可在组件中正常遍历使用的格式。
解决方法
报错核心原因是遍历过程中直接将嵌套对象放到了JSX的渲染位置,React无法将普通JS对象解析为DOM节点。不需要修改原始数据的键值结构,只要在渲染阶段判断值的类型,避免直接输出对象即可,两种常用实现方案:
方案1:按已知结构定向渲染(生产环境推荐)
业务场景下数据结构通常是固定的,直接解构取对应基础类型字段渲染即可,代码可维护性高,不会出现类型错误:
export default function Footer({ data }) { const { type, company_data } = data; const { phone, email, page1, page2 } = company_data; return ( <div className="footer"> <div className="footer-type">{type}</div> <div className="contact"> <p>联系电话:{phone}</p> <p>联系邮箱:{email}</p> </div> <div className="footer-links"> <a href={page1.url}>{page1.title}</a> <a href={page2.url}>{page2.title}</a> </div> </div> ); }
方案2:递归遍历渲染(适合动态不确定结构)
如果数据结构动态变化无法提前枚举字段,可以写递归渲染逻辑:遇到字符串、数字这类基础类型直接渲染,遇到对象/数组则继续递归遍历内部属性,从根源避免直接渲染对象:
// 递归渲染嵌套对象的工具方法 const renderObj = (target) => { return Object.entries(target).map(([key, value]) => { // 基础类型值直接渲染 if (typeof value !== 'object' || value === null) { return ( <div key={key} style={{ margin: '4px 0' }}> <strong>{key}:</strong> {value} </div> ) } // 嵌套对象递归渲染子级 return ( <div key={key} style={{ marginLeft: '16px' }}> <div><strong>{key}:</strong></div> {renderObj(value)} </div> ) }) } export default function Footer({ data }) { return ( <div className="footer"> {renderObj(data)} </div> ); }
注意事项
- 遍历生成的JSX元素必须添加唯一
key属性,避免React渲染diff警告 - 永远不要直接把普通对象、数组放到JSX的
{}插值位置直接渲染,要么取内部的基础类型字段,要么做遍历/格式化处理 - 不建议为了规避报错直接用
JSON.stringify把对象转成字符串渲染,会丢失结构语义,无法实现链接跳转这类交互。
内容的提问来源于stack exchange,提问作者flinch85
相关产品推荐
相关产品推荐

