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

如何实现Material UI图标的动态/懒加载,避免导入全部图标模块?

动态导入Material UI图标(避免全量导入)

当前我通过全量导入所有图标的方式实现了动态渲染,但不想引入无关图标:

import * as Icons from '@mui/icons-material';

对应的组件代码:

import { createElement } from 'react';
import * as Icons from '@mui/icons-material';

export const MaterialUIIcon = ({ iconName }) => {
    return createElement(Icons[iconName]);
};

请问有没有办法通过字符串导入单个图标?我试过类似React.lazy(() => import('@mui/icons-material/${iconName}'))的写法,但没生效。


可行解决方案

方案1:React.lazy + Suspense 懒加载实现

之前的写法错误在于模板字符串用了单引号,且没有正确处理图标组件的导出方式(Material UI图标是命名导出,而React.lazy默认识别默认导出)。修正后的代码:

import { lazy, Suspense } from 'react';

export const MaterialUIIcon = ({ iconName }) => {
  // 用反引号包裹模板字符串,将命名导出转为默认导出
  const IconComponent = lazy(() => 
    import(`@mui/icons-material/${iconName}`).then(module => ({ default: module[iconName] }))
  );

  return (
    <Suspense fallback={<div>加载中...</div>}>
      <IconComponent />
    </Suspense>
  );
};

方案2:无懒加载的动态导入

如果不需要懒加载,可以直接通过useEffect动态导入并渲染:

import { useState, useEffect } from 'react';

export const MaterialUIIcon = ({ iconName }) => {
  const [IconComponent, setIconComponent] = useState(null);

  useEffect(() => {
    const loadIcon = async () => {
      const module = await import(`@mui/icons-material/${iconName}`);
      setIconComponent(module[iconName]);
    };

    loadIcon();
  }, [iconName]);

  if (!IconComponent) {
    return <div>加载中...</div>;
  }

  return <IconComponent />;
};

注意事项

  • iconName必须严格匹配Material UI图标的组件名(如Home、AccountCircle,大小写敏感)
  • 打包工具(Webpack/Vite)会自动做代码分割,每个图标会被打包为单独的chunk,避免全量导入的体积问题
  • 若频繁切换图标,可添加缓存逻辑(比如用useRef存储已加载的组件),减少重复请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 09:25:21