React映射对象数组时如何动态传参渲染JSX组件?
解决方法
要实现动态传递props给图标组件,需要修改三个核心部分:类型定义、侧边栏数据结构,以及渲染逻辑。
1. 修改TypeScript类型定义
把IconComponent的类型从JSX.Element改为React.ElementType——这个类型可以接收任何React组件(函数组件、类组件都支持),而非提前渲染好的静态元素:
sidebarData: { title: string; link: string; IconComponent: React.ElementType; // 可选:如果需要存默认props,可添加该字段 defaultProps?: Record<string, unknown>; }[];
2. 更新侧边栏数据
将原来的<IconDashboard className="icon" />改为直接引用组件本身,不要提前渲染。如果有固定的默认属性,后续可以在渲染阶段合并:
export const adminSidebarData: SidebarProps["sidebarData"] = [ { title: "Dashboard", link: "/admin/dashboard", IconComponent: IconDashboard, // 直接传组件,不是渲染后的元素 defaultProps: { className: "icon" }, // 可选:存默认属性 }, { title: "Users", link: "/admin/dashboard/users", IconComponent: IconDashboard, } ];
3. 修改渲染逻辑
现在可以用组件标签的方式渲染,并且动态传递props了。比如根据当前路由判断激活状态,设置不同的颜色或类名:
// 以Next.js为例,用useRouter获取当前路由 import { useRouter } from 'next/router'; // 组件内部逻辑 const router = useRouter(); {sidebarData.map((data) => { const isActive = router.pathname === data.link; return ( <Link href={data.link} className="w-full" key={data.link}> <div className={`mx-2 flex w-full px-2 py-2 ${isActive ? 'bg-blue-100' : 'bg-white'}`} > {/* 用组件标签渲染,合并默认props与动态props */} <data.IconComponent {...data.defaultProps} className={`${data.defaultProps?.className || ''} ${isActive ? 'text-blue-600' : 'text-gray-600'}`} /> <p className={`${isActive ? 'text-blue-600' : 'text-gray-600'}`}>{data.title}</p> </div> </Link> ); })}
关键原理说明
原来的写法是提前渲染好图标元素(JSX.Element),相当于把静态DOM存进了数组,自然无法再动态修改props。改成存储组件本身(React.ElementType)后,渲染时才会创建元素,这时候就能灵活传入动态属性了。
内容的提问来源于stack exchange,提问作者Bikrant
相关产品推荐
相关产品推荐

