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

React TypeScript中如何动态添加Material-UI图标?

动态加载Material-UI图标失败的解决方法

问题描述

我有一个带图标的菜单,将其存储在对象数组中,其中图标标签名以Material-UI中的字符串形式保存:

interface MenuButton {
    text: string,
    onClickFunction: Function
    icon: string
}

export default function Catalog() {    
    ...
    const generalButtons: MenuButton[] = [
        {
            text: "New Client",
            onClickFunction: addNewClient,
            icon: "InfoIcon"
        },
        {
            text: "New Product",
            onClickFunction: addNewProduct,
            icon: "AddShoppingCartIcon"
        },
        {
            text: "New Gift",
            onClickFunction: addNewGift,
            icon: "CardGiftcardIcon"
        }
    ]
    ...

随后我尝试在List组件中使用这些图标,以下是我尝试的最简方案,但出现了问题:

return (
    ...
    <List>
        {generalButtons.map((button, index) => {
            const CustomIcon = button.icon
            return (
            <ListItem key={button.text} disablePadding>
                <ListItemButton onClick={(e) => button.onClickFunction(e)}>
                    <ListItemIcon>
                        <CustomIcon />
                    </ListItemIcon>
                    <ListItemText primary={button.text} />
                </ListItemButton>
            </ListItem>
         )
     })}
    </List>
)

图标并未显示,反而出现如下错误:

Warning: <InfoIcon /> is using incorrect casing. Use PascalCase for React components, or lowercase for HTML elements.

解决方法

问题核心是你把字符串当作React组件直接渲染了——React无法识别字符串形式的组件名,只会把它当作普通HTML标签处理,因此触发大小写错误。解决思路是先将Material-UI图标组件映射为键值对,再通过字符串键获取对应组件。

1. 导入目标图标组件

先确保你已导入所有用到的Material-UI图标:

import InfoIcon from '@mui/icons-material/Info';
import AddShoppingCartIcon from '@mui/icons-material/AddShoppingCart';
import CardGiftcardIcon from '@mui/icons-material/CardGiftcard';

2. 创建图标映射对象

定义一个对象,将图标名称字符串与对应的组件关联:

const iconMap = {
  InfoIcon: InfoIcon,
  AddShoppingCartIcon: AddShoppingCartIcon,
  CardGiftcardIcon: CardGiftcardIcon
};

3. 优化类型定义(可选但推荐)

为了保证TypeScript类型安全,修改MenuButton接口的icon字段类型,限定为iconMap的键:

type IconKey = keyof typeof iconMap;

interface MenuButton {
    text: string;
    onClickFunction: (e: React.MouseEvent) => void;
    icon: IconKey;
}

4. 渲染时获取正确组件

在map循环中,从iconMap取出对应组件再渲染:

return (
    ...
    <List>
        {generalButtons.map((button) => {
            const IconComponent = iconMap[button.icon];
            return (
            <ListItem key={button.text} disablePadding>
                <ListItemButton onClick={(e) => button.onClickFunction(e)}>
                    <ListItemIcon>
                        <IconComponent />
                    </ListItemIcon>
                    <ListItemText primary={button.text} />
                </ListItemButton>
            </ListItem>
         )
     })}
    </List>
)

内容的提问来源于stack exchange,提问作者András Krausz

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.17 17:42:43