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

React引入SVG文件报相邻JSX元素需包裹闭合标签错误

React + Chakra UI 引入多根节点SVG编译报错解决方案

问题复现

  • 技术栈:React + Chakra UI
  • 编译报错信息:
Compiled with problems:X

ERROR

[eslint] 
src/svg/banner.jsx
  Line 15:2:  Parsing error: Adjacent JSX elements must be wrapped in an enclosing tag. Did you want a JSX fragment <>...</>? (15:2)
  • 异常SVG特征:代码包含2个并列的根级<svg>标签,无统一父容器
  • 已尝试无效的引入方式:
    • 作为React组件引入:import { ReactComponent as Logo } from "../svg/banner.svg";
    • 作为静态资源引入:import banner from "../svg/banner.svg";

报错原因

JSX语法强制要求单个组件只能返回一个根节点,直接将两个并列的SVG标签放在JSX文件中解析时,会违反单根节点规则触发ESLint解析错误。同时原生SVG文件规范和构建工具的SVG解析loader均不支持多根节点的SVG文件直接被解析为React组件或可正常加载的静态资源。

可行解决方案

方案1:用React Fragment包裹并列SVG(最快适配已写好的JSX格式SVG)

如果已经把SVG代码放在.jsx后缀的文件中,直接用React Fragment(空标签)把两个并列的SVG标签包裹即可,不需要引入额外依赖:

// src/svg/banner.jsx
const BannerSvg = () => {
  return (
    <>
      <svg width="100" height="100" xmlns="http://www.w3.org/2000/svg">
        <circle
          cx="50"
          cy="50"
          r="40"
          stroke="blue"
          fill="lightblue"
        />
      </svg>
      <svg
        xmlns="http://www.w3.org/2000/svg"
        xmlns:xlink="http://www.w3.org/1999/xlink"
        width="1921.641"
        height="170.5"
        viewBox="0 0 1921.641 170.5"
      >
        <defs>
          <linearGradient
            id="linear-gradient"
            x1="-0.038"
            y1="-1.902"
            x2="1.1"
            y2="2.41"
            gradientUnits="objectBoundingBox"
          >
            <stop offset="0" stop-color="#4040be" />
            <stop offset="0.36" stop-color="#4e67eb" />
            <stop offset="1" stop-color="#31c3ac" />
          </linearGradient>
        </defs>
        <path
          id="Path_30"
          data-name="Path 30"
          d="M0,0H1921.641V170.5H0Z"
          opacity="0.8"
          fill="url(#linear-gradient)"
        />
      </svg>
    </>
  )
}
export default BannerSvg;

使用时直接引入组件渲染即可:

import BannerSvg from "../svg/banner.jsx";

// 组件内调用
<BannerSvg />

注意:如果页面中存在其他SVG,建议修改当前SVG内的渐变id值,避免id重名导致样式冲突。

方案2:合并为单根节点SVG(保留.svg文件格式)

如果需要保留文件为.svg后缀,使用ReactComponent或静态资源方式引入,可新增一个根级SVG标签,将两个原有SVG作为子节点放入,根据布局需求调整子SVG的坐标和整体视口大小即可:

<!-- banner.svg -->
<svg
  xmlns="http://www.w3.org/2000/svg"
  xmlns:xlink="http://www.w3.org/1999/xlink"
  viewBox="0 0 1921.641 270.5"
>
  <!-- 圆形SVG,可根据实际布局需求调整x/y坐标 -->
  <svg width="100" height="100" y="170.5">
    <circle
      cx="50"
      cy="50"
      r="40"
      stroke="blue"
      fill="lightblue"
    />
  </svg>
  <!-- 渐变背景SVG -->
  <svg
    width="1921.641"
    height="170.5"
    viewBox="0 0 1921.641 170.5"
  >
    <defs>
      <linearGradient
        id="banner-linear-gradient"
        x1="-0.038"
        y1="-1.902"
        x2="1.1"
        y2="2.41"
        gradientUnits="objectBoundingBox"
      >
        <stop offset="0" stop-color="#4040be" />
        <stop offset="0.36" stop-color="#4e67eb" />
        <stop offset="1" stop-color="#31c3ac" />
      </linearGradient>
    </defs>
    <path
      id="Path_30"
      data-name="Path 30"
      d="M0,0H1921.641V170.5H0Z"
      opacity="0.8"
      fill="url(#banner-linear-gradient)"
    />
  </svg>
</svg>

处理完成后即可正常使用两种原有引入方式:

  • 组件方式引入:import { ReactComponent as BannerLogo } from "../svg/banner.svg"; 直接渲染<BannerLogo />
  • 静态资源方式引入:import banner from "../svg/banner.svg"; 通过img标签或Chakra UI的Image组件渲染

方案3:适配Chakra UI组件渲染

合并为单根SVG后,可直接使用Chakra UI内置的Image组件渲染静态资源引入的SVG,方便快速配置样式:

import { Image } from '@chakra-ui/react'
import banner from "../svg/banner.svg";

<Image src={banner} alt="page banner" w="100%" objectFit="cover" />

内容的提问来源于stack exchange,提问作者Rogestav

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 13:18:16