如何在React中将public文件夹内的SVG通过SVGR作为组件导入?
能否将public文件夹中的SVG导入为React组件?
不行,你提供的代码方式无法实现目标。原因是:{ ReactComponent as MySvg } 这种导入语法是由React打包工具(比如Create React App的Webpack配置、Vite的SVG插件)提供的特性,这类工具只会处理src目录内的资源文件,而public文件夹中的文件会被直接复制到构建产物目录,不会经过loader解析转换,因此无法被转换成React组件。
如果你确实需要将SVG作为React组件使用,有以下几种可行方案:
方案1:将SVG文件移动到src目录(最推荐)
把public下的SVG文件迁移到src目录内(比如src/assets/svg/mysvg.svg),之后就能用你原本的代码导入使用:
import { ReactComponent as MySvg } from '../assets/svg/mysvg.svg'; // 路径根据实际目录结构调整 const MyComponent = () => { return ( <div> <MySvg /> </div> ); }; export default MyComponent;
这种方式完全符合打包工具的默认逻辑,还能直接通过props控制SVG的颜色、尺寸等属性,是最省心的解决方案。
方案2:手动将SVG代码转换为React组件
如果必须保留SVG在public文件夹,可以手动提取SVG代码并封装成组件:
- 打开public中的
mysvg.svg文件,复制<svg>标签内的所有内容(去掉开头的<?xml...?>和<!DOCTYPE...>声明) - 将代码直接写入React组件,或者单独存为
.jsx/.tsx文件
示例:
// 封装成独立组件 const MySvg = ({ fill = 'currentColor', width = '24px', height = '24px' }) => ( <svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill={fill} width={width} height={height} > {/* 这里粘贴你复制的SVG路径等内容 */} <path d="M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2zm1 17h-2v-2h2v2zm2.07-7.75l-.9.92C13.45 12.9 13 13.5 13 15h-2v-.5c0-1.1.45-2.1 1.17-2.83l1.24-1.26c.37-.36.59-.86.59-1.41 0-1.1-.9-2-2-2s-2 .9-2 2H8c0-2.21 1.79-4 4-4s4 1.79 4 4c0 .88-.36 1.68-.93 2.25z" /> </svg> ); const MyComponent = () => { return ( <div> {/* 可以直接传递props控制样式 */} <MySvg fill="#ff0000" width="32px" /> </div> ); }; export default MyComponent;
方案3:动态加载并渲染SVG(适合动态场景)
如果需要从public文件夹动态加载SVG并作为组件使用,可以通过fetch获取SVG文本,再用dangerouslySetInnerHTML渲染:
import { useState, useEffect } from 'react'; const MySvg = () => { const [svgContent, setSvgContent] = useState(''); useEffect(() => { fetch('/assets/svg/mysvg.svg') .then(res => res.text()) .then(rawSvg => { // 清理SVG文本,移除不必要的声明 const cleanedSvg = rawSvg.replace(/^<\?xml.*?\?>|<!DOCTYPE.*?>/g, '').trim(); setSvgContent(cleanedSvg); }); }, []); return ( <div dangerouslySetInnerHTML={{ __html: svgContent }} /> ); }; const MyComponent = () => { return ( <div> <MySvg /> </div> ); }; export default MyComponent;
注意:这种方式无法直接通过props修改SVG属性,若需要控制样式,可在清理文本时替换对应属性值(比如替换fill="#000"为fill="currentColor")。
内容的提问来源于stack exchange,提问作者Louis Lecouturier
相关产品推荐
相关产品推荐

