如何在JavaScript Map中存储并渲染React SVG组件
问题修复与实现方案
现有代码报错原因
两个问题导致报错:
- JSX语法要求大写开头的变量名才会被识别为React组件,且标签必须闭合,你原来的代码里
<Logo_One fill="blue">既没有闭合,变量命名带下划线虽然不影响运行,但容易和编译规则冲突 - 如果修正写法后仍然提示「got: object」,说明你从Map里取到的不是合法React组件,大概率是SVG导入配置不对:CRA默认支持
import { ReactComponent as Xxx } from 'xxx.svg'的写法,Vite/自定义webpack项目需要配置对应的SVG转组件loader(比如vite-plugin-svgr、svg-react-loader),否则默认导入的是SVG资源路径字符串/资源对象,自然无法作为组件渲染。
直接修复现有代码
调整MyComponent的写法即可正常渲染:
import { LogoMap } from "data/LogoMap"; function MyComponent() { // 赋值给大写开头的变量,符合JSX组件识别规则 const LogoOne = LogoMap.get("1"); // 加容错,避免key不存在时直接报错 if (!LogoOne) return null; return ( // 标签自闭合,正常传递fill属性 <LogoOne fill="blue" /> ); }
更推荐的实现方式
用Map存SVG组件本身没有问题,但实际项目里有更易维护的写法,根据场景选即可:
- 如果是静态引入固定Logo,不需要动态切换,直接建统一出口文件导出所有SVG组件即可,不用维护Map的key映射,避免key写错找不到组件的问题:
// src/components/Logos/index.js export { ReactComponent as Logo1 } from "assets/MyLogo.svg"; export { ReactComponent as Logo2 } from "assets/OtherLogo.svg"; // 所有SVG组件统一从这里导出
使用时直接按需导入:
import { Logo1 } from "components/Logos"; function Demo() { return <Logo1 fill="blue" /> }
- 如果确实需要根据字符串key动态切换Logo(比如配置项、后端返回字段控制渲染的图标),用普通对象替代Map写法更简洁,性能也没有差异:
// LogoMap.js import { ReactComponent as Logo1 } from "assets/MyLogo.svg"; import { ReactComponent as Logo2 } from "assets/OtherLogo.svg"; export const logoMap = { "1": Logo1, "2": Logo2, // 其余映射关系 };
动态渲染时加一层容错即可:
import { logoMap } from "data/LogoMap"; function Demo({ logoKey }) { const CurrentLogo = logoMap[logoKey]; return CurrentLogo ? <CurrentLogo fill="blue" /> : null; }
小技巧:可以把SVG文件里写死的fill属性值改成
currentColor,之后不需要单独给SVG组件传fill,只要给组件外层元素设置color属性,就能继承控制SVG颜色,使用更灵活。
内容的提问来源于stack exchange,提问作者Nick Schneider
相关产品推荐
相关产品推荐

