React.js如何创建可复用自定义图标组件并加载本地SVG资源
MyIcon组件接入SVG资源实现方案
你现有代码的核心问题是直接将name属性作为img标签的src传入,没有关联已导入的SVG资源路径,同时图标用数组存储需要遍历查找,类型定义和实际资源也没有绑定,容易出现漏导入、传值错误的问题。按以下步骤调整即可:
第一步:重构图标资源存储结构
把原来的数组结构改为键值对映射表,省去遍历查找的成本,同时可以直接从映射表自动推导图标名称类型,不需要手动维护联合类型,新增图标时自动同步类型。
// src/assets/icons/index.ts (图标资源统一导出文件) import arrowExpand from 'src/assets/images/arrow_expand.svg'; import avatar from 'src/assets/images/avatar.svg'; import dashboard from 'src/assets/images/dashboard.svg'; // 补全类型中已定义但未导入的dashboard图标资源 // 图标名到资源路径的映射 export const iconMap = { arrowIcon: arrowExpand, avatarIcon: avatar, dashboardIcon: dashboard, } as const; // 自动推导图标名称联合类型,无需手动编写 export type IconName = keyof typeof iconMap;
第二步:调整MyIcon组件逻辑
组件内直接通过传入的name从映射表取对应SVG资源路径,增加异常兜底,同时支持透传原生img属性方便自定义样式、尺寸:
import { iconMap, IconName } from 'src/assets/icons'; type MyIconProps = { name: IconName; alt?: string; } & React.ImgHTMLAttributes<HTMLImageElement>; // 继承原生img所有属性,支持传入className、width、height等 const MyIcon = ({ name, alt, ...restProps }: MyIconProps) => { const iconPath = iconMap[name]; // 异常兜底:传入不存在的图标名时不渲染碎图 if (!iconPath) return null; return ( <img src={iconPath} alt={alt ?? name} {...restProps} /> ); }; export default MyIcon;
使用示例
调整完成后直接传入对应name即可渲染,同时支持自定义尺寸、样式:
// 基础使用 <MyIcon name="arrowIcon" /> // 自定义尺寸和样式 <MyIcon name="avatarIcon" width={24} height={24} className="user-avatar" />
额外优化点
- 后续新增SVG图标时,只需要在
iconMap中新增一条对应配置,TS会自动补全类型提示,不需要修改组件代码 - 如果需要支持内联SVG渲染(方便改颜色、控制SVG内部节点),可以把构建工具的SVG导入规则改为返回React组件,替换img标签为对应SVG组件即可
- 可以根据业务需求增加默认尺寸、默认样式配置,统一项目图标规范
内容的提问来源于stack exchange,提问作者I3art0sh
相关产品推荐
相关产品推荐

