在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>
相关推荐
随风行酱7 小时前
前端工程师的副业之路:周末跑滴滴的真实体验
前端·javascript·ai编程
北城笑笑7 小时前
Vibe Coding 主流 AI 编程工具:Claude Code 与 Codex 全面解析( Claude and Codex )
前端·ai·ai编程·fpga
Darling噜啦啦7 小时前
JS 数据结构实战:从栈队列到链表,一文吃透数组底层原理与线性数据结构
前端·javascript·数据结构
Asize8 小时前
重生之我在 Vibe Coding 时代当程序员:第十五课,正则表达式和 HTTP 请求:规则不是背出来的,是拆出来的
前端·javascript·后端
Mintopia8 小时前
从意图到评估:理解用户操作产品的完整行动链路
前端
竹林8188 小时前
从报错到跑通:我用 @solana/web3.js 在 React 中实现 Solana 钱包连接的全过程
前端
Asize8 小时前
重生之我在 Vibe Coding 时代当程序员:第十六课,从模拟队列到原型链
前端·javascript·后端
vim怎么退出8 小时前
Dive into React——高级特性
前端·react.js·源码阅读
如果超人不会飞8 小时前
TinyVue Container 组件完全指南:五种版型撑起你的"应用骨架"
前端·vue.js
冰暮流星8 小时前
javascript之this关键字
开发语言·前端·javascript