React组件渲染数组报错:Objects are not valid as a React child 求助
问题解决:React渲染导航数据报错"Objects are not valid as a React child"
报错原因
你两次尝试都犯了同一个核心错误:直接将subMenu数组(内部是对象)作为React子元素渲染。React无法直接解析对象类型的内容,必须把每个子菜单对象转换成可渲染的React元素(比如<div>、<li>等)。你只在外层navigation数组用了map(),但内层的subMenu数组同样需要用map()遍历处理。
另外,你的显示隐藏逻辑存在问题:当前用的是单个ShowSubMenu状态,会导致所有子菜单同时展开/收起,应该给每个主菜单分配独立的展开状态。
修正后的完整代码示例
import { useState } from 'react'; import ChevronDownIcon from '@heroicons/react/24/solid/ChevronDownIcon'; const navigation = [ { name: "Services", description: "Our services", href: "#", subMenu: [ { name: "Management" }, { name: "Development" }, { name: "Specialists" }, ], }, { name: "Experts", description: "our experts", href: "#", subMenu: [ { name: "Engineers" }, { name: "Project managers" }, { name: "Developers" }, { name: "Cloud solutions" }, ], }, ]; export default function Navigation() { // 用对象存储每个主菜单的展开状态,初始都为false const [showSubMenus, setShowSubMenus] = useState({}); const toggleSubMenu = (menuName) => { setShowSubMenus(prev => ({ ...prev, [menuName]: !prev[menuName] })); }; return ( <div className="space-y-4"> {navigation.map((item) => ( <div key={item.name} className="border-b pb-4"> <div className="flex justify-between items-center"> <h3 className="underline-offset-2">{item.description}</h3> <ChevronDownIcon onClick={() => toggleSubMenu(item.name)} className={`h-5 w-5 transition-transform ${showSubMenus[item.name] ? 'rotate-180' : ''}`} /> </div> {/* 遍历subMenu数组,渲染每个子项的name */} {showSubMenus[item.name] && ( <div className="mt-2 pl-4 space-y-2"> {item.subMenu.map((subItem) => ( <div key={subItem.name}>{subItem.name}</div> ))} </div> )} </div> ))} </div> ); }
关键修正点
- 内层遍历子菜单:对
item.subMenu使用map(),将每个子对象的name属性渲染成具体的元素,解决对象无法作为React子元素的问题。 - 独立的展开状态:用对象
showSubMenus存储每个主菜单的展开状态,点击时只切换当前菜单的状态,避免所有子菜单同步变化。 - 条件渲染子菜单:通过
showSubMenus[item.name]判断是否显示当前子菜单,配合图标旋转提升交互体验。
内容的提问来源于stack exchange,提问作者Tihi
相关产品推荐
相关产品推荐

