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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.30 05:57:17