You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在React项目中正确使用SVG Sprite?

在React中使用SVG Sprite的问题

我在Stack Overflow上搜索了许多相关问题,但都没有解决我的问题。我拥有一个SVG Sprite:

<svg width="25" height="25" >
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" id="dota-icon">
    <path d="M46,8V6c0-0.552-0.447-1-1-1h-4c-0.396,0-0.714,0.026-1,0.1V5c0-0.552-0.447-1-1-1h-6c-1.734,0-2.361,0.984-2.729,2h-0.812 C29.226,5.689,29,5.286,29,5c0-0.552-0.447-1-1-1h-7c-0.511,0-0.94,0.393-0.995,0.9C19.982,5.11,19.557,6,18.896,6h-2.74 c-0.065-0.077-0.159-0.22-0.24-0.403C15.756,5.234,15.396,5,15,5H5C4.447,5,4,5.448,4,6v8c0,2.823,0.825,6.397,0.999,7.118 l-0.008,1.515l-0.678,0.641C4.113,23.462,4,23.725,4,24v4c0,0.266,0.105,0.52,0.293,0.707L5,29.414v4.424l-0.948,2.846 c-0.061,0.181-0.068,0.374-0.021,0.559l0.929,3.718l-0.907,2.724c-0.103,0.305-0.051,0.641,0.137,0.901C4.377,44.846,4.679,45,5,45 h14c0.266,0,0.52-0.105,0.707-0.293l0.09-0.09C20.328,45.343,21.067,46,22,46h3c0.736,0,1.38-0.321,1.947-0.605 C27.335,45.2,27.736,45,28,45h5c0.266,0,0.52-0.105,0.707-0.293l0.243-0.243c0.063,0.08,0.123,0.159,0.182,0.235 C34.623,45.339,35.13,46,36,46h5c0.553,0,1-0.447,1-1v-0.719l2.758,0.688c0.299,0.077,0.616,0.007,0.86-0.184 c0.243-0.19,0.384-0.483,0.382-0.793c-0.001-0.098-0.063-9.91,0-14.98c0.003-0.27-0.103-0.529-0.293-0.72L45,27.586V23 c0-0.265-0.105-0.52-0.293-0.707l-0.49-0.49l0.605-1.21l0.885-0.885C45.895,19.52,46,19.265,46,19l-0.015-5.01 c0-0.081-0.01-0.161-0.029-0.24l-0.896-3.632l0.835-1.67C45.964,8.309,46,8.155,46,8z M34.089,12l3.044,2l-1.015,6L28,14L34.089,12z M15,38l-4-3l2-7l8,8L15,38z M36.2,37h-4.667L11,12.926L14.733,12L39,30.518L36.2,37z"></path>
  </symbol>
</svg>

我尝试通过以下方式使用它:

<use xlinkHref="../../img/svg-sprite.svg#icon-dota" />

或者:

<svg width="10" height="10">
  <use xlinkHref="../../img/svg-sprite.svg#icon-dota"></use>
</svg>

之后我尝试将其作为ReactComponent导入,但遇到了错误:Cannot find module "../../img/svg-sprite.svg" or associated type declarations.

我找到了一个解决方案但没起作用:

const webpack = require('webpack');

module.exports = {
  module: {
    rules: [
      //...
      {
        test: /\.svg$/,
        use: ['@svgr/webpack'],
      },
    ],
  },
  //...
};

解决方法

1. 修正ID匹配错误

首先注意:你的Sprite中symbol的id是dota-icon,但你使用时写的是#icon-dota,ID不匹配是核心问题之一,先统一改为#dota-icon。

2. 直接在HTML中引入Sprite(最简单方案)

  • 将svg-sprite.svg放在项目的public目录下
  • 在public/index.html的<body>开头添加:
<svg style="display: none;">
  <symbol xmlns="http://www.w3.org/2000/svg" viewBox="0 0 50 50" id="dota-icon">
    <path d="M46,8V6c0-0.552-0.447-1-1-1h-4c-0.396,0-0.714,0.026-1,0.1V5c0-0.552-0.447-1-1-1h-6c-1.734,0-2.361,0.984-2.729,2h-0.812 C29.226,5.689,29,5.286,29,5c0-0.552-0.447-1-1-1h-7c-0.511,0-0.94,0.393-0.995,0.9C19.982,5.11,19.557,6,18.896,6h-2.74 c-0.065-0.077-0.159-0.22-0.24-0.403C15.756,5.234,15.396,5,15,5H5C4.447,5,4,5.448,4,6v8c0,2.823,0.825,6.397,0.999,7.118 l-0.008,1.515l-0.678,0.641C4.113,23.462,4,23.725,4,24v4c0,0.266,0.105,0.52,0.293,0.707L5,29.414v4.424l-0.948,2.846 c-0.061,0.181-0.068,0.374-0.021,0.559l0.929,3.718l-0.907,2.724c-0.103,0.305-0.051,0.641,0.137,0.901C4.377,44.846,4.679,45,5,45 h14c0.266,0,0.52-0.105,0.707-0.293l0.09-0.09C20.328,45.343,21.067,46,22,46h3c0.736,0,1.38-0.321,1.947-0.605 C27.335,45.2,27.736,45,28,45h5c0.266,0,0.52-0.105,0.707-0.293l0.243-0.243c0.063,0.08,0.123,0.159,0.182,0.235 C34.623,45.339,35.13,46,36,46h5c0.553,0,1-0.447,1-1v-0.719l2.758,0.688c0.299,0.077,0.616,0.007,0.86-0.184 c0.243-0.19,0.384-0.483,0.382-0.793c-0.001-0.098-0.063-9.91,0-14.98c0.003-0.27-0.103-0.529-0.293-0.72L45,27.586V23 c0-0.265-0.105-0.52-0.293-0.707l-0.49-0.49l0.605-1.21l0.885-0.885C45.895,19.52,46,19.265,46,19l-0.015-5.01 c0-0.081-0.01-0.161-0.029-0.24l-0.896-3.632l0.835-1.67C45.964,8.309,46,8.155,46,8z M34.089,12l3.044,2l-1.015,6L28,14L34.089,12z M15,38l-4-3l2-7l8,8L15,38z M36.2,37h-4.667L11,12.926L14.733,12L39,30.518L36.2,37z"></path>
  </symbol>
</svg>
  • 在React组件中直接使用:
<svg width="25" height="25">
  <use href="#dota-icon" />
</svg>

注意:xlinkHref是SVG 1.1的旧属性,现代浏览器支持直接用href。

3. 使用svg-sprite-loader打包Sprite

适合需要通过webpack管理资源的场景:

  1. 安装依赖:
npm install svg-sprite-loader --save-dev
  1. 修改webpack配置(Create React App项目需用react-app-rewired或 eject):
module.exports = {
  module: {
    rules: [
      {
        test: /\.svg$/,
        loader: 'svg-sprite-loader',
        options: {
          symbolId: 'icon-[name]' // 生成的symbol ID格式,可自定义
        }
      }
    ]
  }
};
  1. 在React组件中导入并使用:
import '../../img/svg-sprite.svg';

export default function DotaIcon() {
  return (
    <svg width="25" height="25">
      <use href="#dota-icon" />
    </svg>
  );
}

4. 解决TypeScript类型声明问题

如果是TypeScript项目,创建src/types/svg.d.ts文件:

declare module '*.svg' {
  const content: string;
  export default content;
}

然后在tsconfig.json中确保包含该类型文件:

{
  "compilerOptions": {
    "typeRoots": ["./src/types", "./node_modules/@types"]
  }
}

关键注意事项

  • 不要用@svgr/webpack处理Sprite文件,它的作用是将单个SVG转换为React组件,不适合多symbol的Sprite
  • 始终确保use的href与Sprite中symbol的id完全匹配
  • 检查文件路径是否正确,webpack解析路径时相对于当前组件文件位置

内容的提问来源于stack exchange,提问作者Богдан Гапоненко

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.12 11:35:54