在React中使用动态图标

背景

需要按名称引入图标

安装

yarn add react-icons

实现

typescript 复制代码
import loadable from "@loadable/component"
import { IconBaseProps, IconType } from "react-icons/lib"

interface typesPropsIcon {
  nameIcon: string;
  propsIcon?: IconBaseProps
}

export function Icon({ nameIcon, propsIcon }: typesPropsIcon): JSX.Element {
  const lib = nameIcon.replace(/([a-z0-9])([A-Z])/g, '$1 $2').split(" ")[0].toLocaleLowerCase();
  const ElementIcon: IconType = loadable(() => import(`react-icons/${lib}/index.js`), {
    resolveComponent: (el: JSX.Element) => el[nameIcon as keyof JSX.Element]
  });

  return (<span style={{paddingRight: 6}}><ElementIcon {...propsIcon} style={{size: '1em'}}/></span>)

示例

typescript 复制代码
<Space direction="horizontal">
      <Menu
        mode="inline"    
        style={{ width: 500, height:'fit-content' }}    
        items={[
          { key: 'mail', label: 'Mail1', icon: <MailOutlined />, type:'group' },
          { key: 'mail2', label: 'Mail2', icon: <Icon nameIcon="AiFillBug" propsIcon={{ size: 20 }} /> },
          { key: 'mail3', label: 'Mail3', icon: <Icon nameIcon="AiFillInsurance" propsIcon={{ size: 20 }}/> },
          { key: 'mail4', label: 'Mail4', icon: <Icon nameIcon="AiFillDollarCircle" propsIcon={{ size: 20 }}/> },
          { key: 'mail5', label: 'Mail5', icon: <Icon nameIcon="AiOutlineApartment" propsIcon={{ size: 20 }}/> },
        ]}        
      />      
      <Menu
        mode="inline" 
        style={{ width: 256, height:'fit-content', marginLeft: 4}}          
        items={[
          { key: 'mail11', label: ' Mail1', icon: <Icon nameIcon="BiAperture" propsIcon={{ size: 20 }}/>, type:'group' },
          { key: 'mail21', label: ' Mail2', icon: <Icon nameIcon="CiBasketball" propsIcon={{ size: 20 }}/> },
          { key: 'mail31', label: ' Mail3', icon: <Icon nameIcon="CiBadgeDollar" propsIcon={{ size: 20 }}/> },
          { key: 'mail41', label: ' Mail4', icon: <Icon nameIcon="CiBoxList" propsIcon={{ size: 20, marginRight: 80, marginBottom: 10 }}/> },
          { key: 'mail51', label: ' Mail5', icon: <ClusterOutlined /> },
        ]}        
      />      
      </Space>
相关推荐
fruge2 小时前
Vue项目中的Electron桌面应用开发实践指南
前端·vue.js·electron
漂流瓶jz8 小时前
Webpack中各种devtool配置的含义与SourceMap生成逻辑
前端·javascript·webpack
这是个栗子8 小时前
【问题解决】用pnpm创建的 Vue3项目找不到 .eslintrc.js文件 及 后续的eslint配置的解决办法
javascript·vue.js·pnpm·eslint
前端架构师-老李8 小时前
React 中 useCallback 的基本使用和原理解析
前端·react.js·前端框架
木易 士心8 小时前
CSS 中 `data-status` 的使用详解
前端·css
明月与玄武8 小时前
前端缓存战争:回车与刷新按钮的终极对决!
前端·缓存·回车 vs 点击刷新
牧马少女8 小时前
css 画一个圆角渐变色边框
前端·css
zy happy9 小时前
RuoyiApp 在vuex,state存储nickname vue2
前端·javascript·小程序·uni-app·vue·ruoyi
小雨青年9 小时前
Cursor 项目实战:AI播客策划助手(二)—— 多轮交互打磨播客文案的技术实现与实践
前端·人工智能·状态模式·交互
Nan_Shu_6149 小时前
学习:JavaScript(5)
开发语言·javascript·学习