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

React中如何通过循环将对象属性渲染为JSX元素?

在React中循环渲染对象属性的正确方式与优化方案

问题背景

我有一个名为tour的对象,结构如下:

const tour = {
  date: dateBetweenFormat(13),// 返回字符串
  where: "NY",
  info: "group full",
  amount: "750$",
  place: "hotel",
};

我希望在React中将该对象的属性渲染为JSX元素,避免重复代码,要求每个属性显示在div中,同时展示属性名作为标签和对应值。

尝试使用for...in循环和Object.entries()遍历对象属性时,出现错误提示:"Objects are not valid as a React child."

尝试的代码

  1. 使用for...in的IIFE写法:
<div className="mb-2">
  {(() => {
    const elements = [];
    for (let key in tour) {
      elements.push(
        <div
          key={key}
          className="flex bg-blue-200 px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60"
        >
          {key}: {tour[key]}
        </div>
      );
    }
    return elements;
  })()}
</div>
  1. 使用Object.entries()的map写法:
<div className="mb-2">
  {Object.entries(tour).map(([key, value]) => (
    <div
      key={key}
      className="flex bg-blue-200 px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60"
    >
      {value}
    </div>
  ))}
</div>

期望输出(排除where属性)

<div className="mb-2">
  <div className="flex bg-blue-200  px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60">
    {tour.date}
  </div>
  <div className="flex bg-blue-200  px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60">
    {tour.info}
  </div>
  <div className="flex bg-blue-200  px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60">
    {tour.amount}
  </div>
  <div className="flex bg-blue-200  px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60">
    {tour.place}
  </div>
</div>

错误原因分析

报错"Objects are not valid as a React child"通常是因为尝试渲染非原始类型的值(比如对象、函数),而React只能渲染字符串、数字、布尔值、JSX元素或null/undefined。

首先排查dateBetweenFormat(13)的返回值:虽然注释说明返回字符串,但实际可能返回了对象或其他非可渲染类型,可通过打印验证:

console.log(typeof dateBetweenFormat(13)); // 确认输出为string

如果返回值没问题,只需调整遍历逻辑以匹配期望输出(排除where属性)即可。


正确实现方式

1. 过滤属性后使用Object.entries()渲染

通过过滤排除不需要的属性,再进行map渲染:

<div className="mb-2">
  {Object.entries(tour)
    .filter(([key]) => key !== 'where') // 排除不需要的属性
    .map(([key, value]) => (
      <div
        key={key}
        className="flex bg-blue-200 px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60"
      >
        {key}: {value} {/* 同时展示属性名和值 */}
      </div>
    ))}
</div>

2. 提取复用组件优化代码

若渲染逻辑需多处使用,建议提取为独立组件,提升复用性和可维护性:

// 定义复用的单个信息项组件
const TourInfoItem = ({ label, value }) => (
  <div className="flex bg-blue-200 px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60">
    {label}: {value}
  </div>
);

// 父组件:控制展示的属性列表
const TourInfo = ({ tour }) => {
  // 明确指定需要展示的属性,更灵活可控
  const displayKeys = ['date', 'info', 'amount', 'place'];
  
  return (
    <div className="mb-2">
      {displayKeys.map(key => (
        <TourInfoItem key={key} label={key} value={tour[key]} />
      ))}
    </div>
  );
};

// 调用组件
<TourInfo tour={tour} />

这种方式的优势:

  • 清晰控制展示内容,无需过滤操作
  • 样式或逻辑修改只需改动一处,维护成本低
  • 符合React组件化思想,代码结构更清晰

3. 修复for...in写法(可选)

若坚持使用for...in,添加属性过滤逻辑即可:

<div className="mb-2">
  {(() => {
    const elements = [];
    const displayKeys = ['date', 'info', 'amount', 'place'];
    for (let key in tour) {
      if (displayKeys.includes(key)) {
        elements.push(
          <div
            key={key}
            className="flex bg-blue-200 px-4 mt-1 h-9 font-bold items-center text-blue-500 text-opacity-60"
          >
            {key}: {tour[key]}
          </div>
        );
      }
    }
    return elements;
  })()}
</div>

关键注意事项

  • 确保所有要渲染的value都是React可接受的原始类型(字符串、数字等),若为对象需提取具体属性后再渲染
  • 遍历渲染时必须给每个JSX元素添加唯一的key属性,避免React警告
  • 使用属性列表(如displayKeys)控制展示内容比过滤更直观,便于后续调整

内容的提问来源于stack exchange,提问作者Murat Turhan

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.19 22:53:09