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

React渲染嵌套数组对象时触发Objects are not valid as a React child错误

解决React中嵌套数组对象渲染的"Objects are not valid as a React child"错误

问题重现

在React项目中渲染嵌套数组内的对象(展示name与value)时,反复触发Objects are not valid as a React child错误,相关代码如下:

状态数据

const [avail, setavail] = useState({
  firstName: '',
  lastName: '',
  mobileNumber: '',
  doctorId: '',
  avalabilities: [
      {
          availabilityId: '',
          day: [
            { name: 'Sunday', value: 'Sunday' },
            { name: 'Monday', value: 'Monday' },
            { name: 'Tuesday', value: 'Tuesday' },
            { name: 'Wednesday', value: 'Wednesday' },
            { name: 'Thursday', value: 'Thursday' },
            { name: 'Friday', value: 'Friday' },
            { name: 'Saturday', value: 'Saturday' },
          ],
          isChecked: false,
          checked: false,
          allChecked: false,
          error: null
      }
  ]
});

原渲染JSX代码

{avail.avalabilities.map((av, avIndex) => (
  <div key={av.availabilityId}>
    {av.day.map((item, index) => (
      <div key={index}>
        <input
          checked={item?.checked || false}
          name={item.name}
          value={item.value}
          onChange={(e) =>
            checkedHandler(e, avIndex, index)
          }
          type="checkbox"
          id={item.value}
        />
        {console.log(item.name)}
        {console.log(item.value)}
        <label htmlFor={item.value}>{item.name}</label>
      </div> 
    ))}

原复选框处理函数

const checkedHandler = (e, avIndex, index) => {
  console.log(e.target.checked, avIndex, index);
  setavail((prev) => {
    let newState = { ...prev };
    newState.avalabilities[avIndex].day[index].checked = e.target.checked;
    return newState;
  });
};

错误原因分析

  1. 状态更新的浅拷贝问题:React状态要求不可变更新,原处理函数仅浅拷贝了外层对象,但avalabilities数组和内部的day数组都是引用类型,直接修改数组内的对象会导致React无法正确检测状态变化,进而引发渲染异常。
  2. JSX标签未闭合:原渲染代码中最外层的<div>标签没有闭合,这会导致React解析JSX时出错,间接触发对象渲染的错误提示。

解决方案

1. 修复状态更新的不可变处理

修改checkedHandler函数,对嵌套的数组和对象进行深拷贝,确保每次状态更新都创建新的引用:

const checkedHandler = (e, avIndex, index) => {
  const isChecked = e.target.checked;
  setavail((prev) => ({
    ...prev,
    avalabilities: prev.avalabilities.map((av, idx) => {
      if (idx !== avIndex) return av;
      return {
        ...av,
        day: av.day.map((item, dayIdx) => {
          if (dayIdx !== index) return item;
          return { ...item, checked: isChecked };
        })
      };
    })
  }));
};

2. 闭合JSX标签

确保所有JSX标签正确闭合,补充原代码中缺失的</div>:

{avail.avalabilities.map((av, avIndex) => (
  <div key={av.availabilityId || avIndex}> {/* 为空key添加兜底值 */}
    {av.day.map((item, index) => (
      <div key={index}>
        <input
          checked={item?.checked || false}
          name={item.name}
          value={item.value}
          onChange={(e) => checkedHandler(e, avIndex, index)}
          type="checkbox"
          id={item.value}
        />
        <label htmlFor={item.value}>{item.name}</label>
      </div> 
    ))}
  </div> {/* 补充闭合标签 */}
))}

3. 移除冗余渲染代码

原JSX中直接嵌入{console.log(item.name)}这类表达式属于冗余代码,建议移除,避免干扰渲染逻辑。

验证说明

修改后,状态更新会遵循React的不可变原则,JSX结构也合法,此时渲染嵌套数组中的item.name和item.value不会再触发对象渲染的错误,复选框的选中状态也能正确同步到状态中。

内容的提问来源于stack exchange,提问作者Disha Singh

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.26 18:05:41