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

React中如何基于state动态生成函数式组件声明?

React动态渲染组件的解决方案

React不支持直接用字符串作为组件名在JSX中渲染,<{component} />这种写法不符合JSX语法规范——JSX要求组件必须是大写开头的React组件引用,而非字符串。以下是具体解决步骤:


1. 导入所有需要动态渲染的组件

先把Menus列表中提到的所有组件导入到SideBar.jsx中:

import { useState } from 'react';
import HomePage from './HomePage';
import Notifications from './Notifications';
import Members from './Members';
import Events from './Events';
import Staff from './Staff';
import Services from './Services';
import Reports from './Reports';
import Settings from './Settings';

2. 创建组件映射表

建立字符串(对应Menus中的title)与实际组件的对应关系,方便通过state值快速匹配组件:

function SideBar() {
  // ... 原有state和Menus数组
  const ComponentMap = {
    HomePage,
    Notifications,
    Members,
    Events,
    Staff,
    Services,
    Reports,
    Settings
  };
  // ... 后续代码
}

3. 动态渲染组件

从映射表中取出当前要渲染的组件,判断存在后再渲染:

return (
  <div className="flex">
    {/* ... 原有侧边栏代码 */}
    <div className="h-screen flex-1 p-7">
      {/* 动态修改页面标题 */}
      <h1 className="text-2xl font-semibold ">
        {component || 'Home Page'}
      </h1>
      {/* 渲染匹配的组件,无匹配时默认显示HomePage */}
      {ComponentMap[component] ? <ComponentMap[component] /> : <HomePage />}
    </div>
  </div>
);

完整修改后的SideBar.jsx代码

import { useState } from 'react';
import HomePage from './HomePage';
import Notifications from './Notifications';
import Members from './Members';
import Events from './Events';
import Staff from './Staff';
import Services from './Services';
import Reports from './Reports';
import Settings from './Settings';

function SideBar() {
  const [open, setOpen] = useState(true);
  const [component, setComponent] = useState('');
  
  const Menus = [
    { id: '1', title: 'HomePage', src: 'Chart_fill' },
    { id: '2', title: 'Notifications', src: 'Chat' },
    { id: '3', title: 'Members', src: 'User', gap: true },
    { id: '4', title: 'Events', src: 'Calendar' },
    { id: '5', title: 'Staff', src: 'Search' },
    { id: '6', title: 'Services', src: 'Chart' },
    { id: '7', title: 'Reports', src: 'Folder', gap: true },
    { id: '8', title: 'Settings', src: 'Setting' },
  ];

  const ComponentMap = {
    HomePage,
    Notifications,
    Members,
    Events,
    Staff,
    Services,
    Reports,
    Settings
  };

  return (
    <div className="flex">
      <div
        className={` ${open ? 'w-72' : 'w-20 '} bg-dark-purple h-screen p-5  pt-8 relative duration-300`}
      >
        <img
          src={require('../assets/control.png')}
          alt="Missing Icon"
          className={`absolute cursor-pointer -right-3 top-10 w-7 border-dark-purple border-2 rounded-full  ${!open && 'rotate-180'}`}
          onClick={() => setOpen(!open)}
        />
        <div className="flex gap-x-4 items-center">
          <img
            src={require('../assets/logo.png')}
            alt="Missing Icon"
            className={`cursor-pointer duration-500 ${open && 'rotate-[360deg]'}`}
          />
          <h1
            className={`text-white origin-left font-medium text-xl duration-200 ${!open && 'scale-0'}`}
          >
            ADCA
          </h1>
        </div>
        <ul className="pt-6">
          {Menus.map((Menu, index) => (
            <li
              onClick={() => {
                component !== Menu.title
                  ? setComponent(Menu.title)
                  : setComponent('');
              }}
              key={index}
              className={`flex rounded-md p-2 cursor-pointer hover:bg-light-white text-gray-300 text-sm items-center gap-x-4 ${Menu.gap ? 'mt-9' : 'mt-2'} ${index === 0 && 'bg-light-white'}`}
            >
              <img
                src={require(`../assets/${Menu.src}.png`)}
                alt="Missing Icon"
              />
              <span className={`${!open && 'hidden'} origin-left duration-200`}>
                {Menu.title}
              </span>
            </li>
          ))}
        </ul>
      </div>
      <div className="h-screen flex-1 p-7">
        <h1 className="text-2xl font-semibold ">
          {component || 'Home Page'}
        </h1>
        {ComponentMap[component] ? <ComponentMap[component] /> : <HomePage />}
      </div>
    </div>
  );
}

export default SideBar;

注意事项

  • 映射表的key必须和Menus数组中的title完全一致,否则无法匹配组件。
  • React要求组件名必须大写开头,否则会被当作普通HTML标签解析。
  • 可根据需求调整默认渲染内容(比如组件为空时显示空白或提示文本)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 09:31:14