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

React应用中如何根据字符串值动态加载使用图标

问题原因

eval 方案报错核心原因有两个:

  • 前端项目普遍使用ES模块搭配Webpack/Vite/Rollup这类打包工具做静态构建,import 导入的变量是模块作用域内的绑定,不会挂载到全局对象,eval 默认从全局作用域查找变量,自然找不到局部导入的Icon1/Icon2。
  • 生产环境打包时会对变量名做压缩混淆,就算作用域匹配正确,硬编码的字符串'Icon1'也无法对应到混淆后的变量名,必然匹配失败,且eval本身存在XSS安全隐患,完全不推荐在业务代码里使用。
可行方案

方案1:手动维护图标映射表(优先推荐)

提前建立字符串标识和图标模块的映射关系,不管你拿到的动态值是变量名还是文件名都能适配,打包工具可以静态分析所有依赖,不会出现资源漏打包的问题,维护成本极低。

import * as Icon1 from 'images/img1.svg'
import * as Icon2 from 'images/img2.svg'

// 映射表key可根据业务传入的动态值灵活调整
const iconMap = {
  // 若传入的是变量名字符串,用以下key
  Icon1,
  Icon2,
  // 若传入的是文件名字符串,替换成以下key即可
  // 'img1.svg': Icon1,
  // 'img2.svg': Icon2,
}

const Foo = () => {
    const theIcon = 'Icon1' // 动态获取的字符串值
    // 配置兜底图标,避免key不存在导致组件渲染报错
    const renderIcon = iconMap[theIcon] || Icon1

    return (<>
        <AComponent icon={renderIcon}/>
    </>)
}

后续新增图标只需要补充import语句和对应映射项即可。

方案2:批量导入图标(适合图标存量大的场景)

如果项目里有几十上百个图标,手动写import太繁琐,可以利用打包工具提供的批量导入能力自动生成映射表。
以Vite环境为例:

// 配置eager: true实现同步导入,无需异步加载
const iconFiles = import.meta.glob('images/*.svg', { eager: true, import: '*' })

// 自动生成「文件名: 图标模块」格式的映射表
const iconMap = Object.fromEntries(
  Object.entries(iconFiles).map(([fullPath, module]) => {
    const fileName = fullPath.split('/').pop()
    return [fileName, module]
  })
)

const Foo = () => {
  const theIcon = 'img1.svg' // 直接传文件名即可匹配
  const renderIcon = iconMap[theIcon]
  return (<>
    <AComponent icon={renderIcon}/>
  </>)
}

Webpack环境可以用require.contextAPI实现同样的批量导入效果。

注意:不要写完全动态的导入语句比如import(images/${iconName}),这类写法会把匹配路径下的所有svg文件都打进生产包,会额外增加包体积,且路径规则不明确时很容易出现资源404的问题,图标数量少的时候优先选方案1。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.27 11:21:22