react-svg vs react-svg-loader vs react-svg-pan-zoom
React SVG 处理库
react-svgreact-svg-loaderreact-svg-pan-zoom类似的npm包:

React SVG 处理库

这些库用于在 React 应用程序中处理 SVG(可缩放矢量图形),提供了不同的功能以满足开发者的需求。它们使得 SVG 的使用变得更加简单和灵活,适用于各种场景,包括图标、图形和复杂的可视化。通过这些库,开发者可以轻松地集成和操作 SVG,提升用户体验和界面美观度。

npm下载趋势

3 年

GitHub Stars 排名

统计详情

npm包名称
下载量
Stars
大小
Issues
发布时间
License
react-svg335,16388382.7 kB117 天前MIT
react-svg-loader78,507637-487 年前MIT
react-svg-pan-zoom36,1786961.02 MB412 年前MIT

功能对比: react-svg vs react-svg-loader vs react-svg-pan-zoom

使用方式

  • react-svg:

    react-svg 允许你直接将 SVG 文件作为 React 组件导入,使用起来非常简单。只需通过 import 语句导入 SVG 文件,然后在 JSX 中使用,就可以轻松集成。

  • react-svg-loader:

    react-svg-loader 通过 webpack 加载 SVG 文件,并将其转换为 React 组件。它提供了灵活的配置选项,允许开发者在构建过程中自定义 SVG 的处理方式。

  • react-svg-pan-zoom:

    react-svg-pan-zoom 提供了丰富的 API 来实现 SVG 的平移和缩放功能。它允许用户通过鼠标或触摸手势与 SVG 进行交互,适合需要动态查看的图形。

交互性

  • react-svg:

    react-svg 的交互性较弱,主要用于静态 SVG 的展示,不支持复杂的用户交互。

  • react-svg-loader:

    react-svg-loader 主要关注于将 SVG 转换为组件,交互性取决于如何使用生成的组件。

  • react-svg-pan-zoom:

    react-svg-pan-zoom 专注于交互性,提供了平移和缩放的功能,适合需要用户与图形进行交互的场景。

性能

  • react-svg:

    react-svg 的性能表现良好,适合小型和中型 SVG 文件的使用,但对于复杂的 SVG,可能会影响渲染性能。

  • react-svg-loader:

    react-svg-loader 的性能与 webpack 配置密切相关,适合在构建时优化 SVG 文件,减少运行时负担。

  • react-svg-pan-zoom:

    react-svg-pan-zoom 在处理复杂的 SVG 时性能良好,能够流畅地实现平移和缩放,但需要注意事件处理的效率。

学习曲线

  • react-svg:

    react-svg 的学习曲线较平缓,开发者可以快速上手,适合初学者。

  • react-svg-loader:

    react-svg-loader 需要一定的 webpack 知识,学习曲线相对较陡,但提供了更强的灵活性。

  • react-svg-pan-zoom:

    react-svg-pan-zoom 的学习曲线适中,开发者需要理解平移和缩放的概念,但 API 设计直观,易于使用。

扩展性

  • react-svg:

    react-svg 的扩展性有限,主要用于简单的 SVG 处理,不支持复杂的功能扩展。

  • react-svg-loader:

    react-svg-loader 提供了较好的扩展性,可以通过 webpack 插件和配置进行自定义处理。

  • react-svg-pan-zoom:

    react-svg-pan-zoom 提供了丰富的 API,可以根据需求进行功能扩展,适合需要复杂交互的应用。

如何选择: react-svg vs react-svg-loader vs react-svg-pan-zoom

  • react-svg:

    选择 react-svg 如果你需要一个简单的解决方案来直接在 React 组件中使用 SVG 文件。它支持将 SVG 文件作为 React 组件导入,易于使用和集成。

  • react-svg-loader:

    选择 react-svg-loader 如果你希望在构建过程中将 SVG 文件转换为 React 组件。它允许你在 webpack 中使用,并提供更多的自定义选项,如添加样式和属性。

  • react-svg-pan-zoom:

    选择 react-svg-pan-zoom 如果你需要在 SVG 中实现平移和缩放功能。这个库专注于交互性,适合需要用户与 SVG 图形进行交互的应用场景。

react-svg的README

react-svg

npm version build status coverage status npm downloads minzipped size

A React component that injects SVG into the DOM.

When To Use This | Basic Usage | API | Live Examples | Installation | Security | FAQ | Contributing | License

When To Use This

This component uses @tanem/svg-injector to fetch an SVG from a given URL and inject its markup into the DOM (why?). Fetched SVGs are cached, so multiple uses of the same SVG only require a single request.

Injection costs a network request and two wrapper elements, and it earns that cost in one case: the SVG's URL isn't known until the app runs, and the markup has to be reachable by CSS. An <img> tag renders an SVG but its contents can't be styled, animated or scripted from the page.

  • SVGs live in your repo and are known at build time. Reach for a build-time transform - SVGR, vite-plugin-svgr, or your bundler's SVG loader. They compile each file to a React component, so there's no runtime fetch, and unused icons are tree-shaken out.
  • The URL is only known at runtime. SVGs from a CMS or an API, user uploads, a CDN-hosted icon set, or a path assembled from data. That's what this component is for.
  • You only need to display the image. Use <img src="https://raw.githubusercontent.com/tanem/react-svg/HEAD/icon.svg">. It's cheaper than either option above.

Basic Usage

import { ReactSVG } from 'react-svg'

const App = () => <ReactSVG src="svg.svg" />

API

Props

PropTypeDefault
srcstringrequired
afterInjection(svg: SVGSVGElement) => voidnoop
beforeInjection(svg: SVGSVGElement) => voidnoop
descstring''
evalScripts'always' | 'once' | 'never''never'
fallbackReact.ElementTypenone
httpRequestWithCredentialsbooleanfalse
loadingReact.ElementTypenone
loadingDelaynumber0
onError(error: unknown) => voidnoop
renumerateIRIElementsbooleantrue
titlestring''
useRequestCachebooleantrue
wrapper'div' | 'span' | 'svg''div'

Errors thrown from beforeInjection and afterInjection are routed to onError and render the fallback, the same as an error raised by the injection itself.

src

The SVG URL. Supports fetchable URLs (relative or absolute), data:image/svg+xml URLs (URL-encoded or base64), and SVG sprite sheets via fragment identifiers (e.g. sprite.svg#icon-star). See the data URL example and sprite usage example.

afterInjection

Called after the SVG is injected. svg is the injected SVG DOM element.

beforeInjection

Called just before the SVG is injected. svg is the SVG DOM element which is about to be injected, so this is where to restyle, class or sanitise it - see Security.

desc

String used for the SVG <desc> element content. If a <desc> exists it is replaced, otherwise a new one is created. When set, a unique id is added to the <desc> element and aria-describedby is set on the SVG for assistive technology. An empty string is a noop.

evalScripts

Whether to run script blocks found in the SVG: 'always', 'once' or 'never'. Leave it at 'never' for SVGs you don't control - see Security.

fallback

Rendered inside the wrapper if an error occurs. Can be a string, class component or function component. Nothing is rendered in its place when unset.

httpRequestWithCredentials

Whether cross-site Access-Control requests for the SVG are made using credentials.

loading

Rendered inside the wrapper until the SVG is injected. Can be a string, class component or function component. Nothing is rendered in its place when unset.

loadingDelay

Milliseconds to wait before rendering loading. At the default 0 it renders immediately. Set a value and an injection that finishes sooner - a warm request cache, a localhost or file:// read, a warm CDN edge - never renders loading at all.

Use it when loading is a spinner, where a sub-second appearance is worse than none: the user can't tell what flashed. Leave it at 0 when loading is a skeleton sized to hold the SVG's space, because delaying that trades one layout shift for two.

200-300ms is the usual industry choice. The delay applies to loading only - fallback always renders as soon as the error arrives, since an error costs a round trip that no cache short-circuits.

onError

Called if an error occurs. error is an unknown value.

renumerateIRIElements

Whether SVG IRI addressable elements are renumerated. When enabled, IDs on IRI-addressable elements (clipPath, linearGradient, mask, path, etc.) are made unique, and all references to them (presentation attributes, href/xlink:href, inline style attributes, and <style> element text) are updated. All matching element types are renumerated, not only those inside <defs>. Set to false if you need to query injected elements by their original IDs.

title

String used for the SVG <title> element content. If a <title> exists it is replaced, otherwise a new one is created. When set, a unique id is added to the <title> element and aria-labelledby is set on the SVG for assistive technology. An empty string is a noop.

useRequestCache

Whether the SVG request cache is used. With it on, repeated uses of the same URL share a single request.

wrapper

The element type used for the wrappers: 'div', 'span' or 'svg'.

Other props

Props not listed above are applied to the outermost wrapper element, so className, style, id, data-* attributes and DOM event handlers behave as they would on the underlying element.

Ref forwarding

A ref is forwarded to the outermost wrapper element, so ref.current is an HTMLDivElement, HTMLSpanElement or SVGSVGElement depending on wrapper. The exported WrapperType type covers all three.

Re-injection

Re-injection happens when src, wrapper, title, desc, evalScripts, httpRequestWithCredentials, renumerateIRIElements or useRequestCache changes. Other props don't affect the injected SVG, so changing them re-renders the wrapper without re-fetching. afterInjection, beforeInjection and onError are always called in their latest form, but changing them doesn't trigger a re-injection on its own, so they can be passed inline.

Example

<ReactSVG
  beforeInjection={(svg) => {
    svg.classList.add('svg-class-name')
    svg.setAttribute('style', 'width: 200px')
  }}
  className="wrapper-class-name"
  desc="Description"
  fallback={() => <span>Error!</span>}
  loading={() => <span>Loading</span>}
  onClick={() => {
    console.log('wrapper onClick')
  }}
  onError={(error) => {
    console.error(error)
  }}
  src="svg.svg"
  title="Title"
  wrapper="span"
/>

Live Examples

Each name links to the example source, and the sandbox column opens it on CodeSandbox.

ExampleSandbox
AccessibilityOpen
API UsageOpen
Basic UsageOpen
Before InjectionOpen
CSS AnimationOpen
CSS-in-JSOpen
Data URLOpen
External StylesheetOpen
FallbacksOpen
IframeOpen
LoadingOpen
No ExtensionOpen
Sprite UsageOpen
SSROpen
Styled ComponentsOpen
SVG WrapperOpen
TypescriptOpen

Installation

$ npm install react-svg

Requires React 16.8 or later, as a peer dependency.

Security

Injected markup becomes part of your page, with the same privileges as anything else in it. That matters whenever src points at something you don't fully control - user uploads, a third-party host, a CMS anyone can write to. An SVG is an XML document that can carry scripts, event handlers and styles, not just shapes.

Scripts are off by default. evalScripts defaults to 'never', so <script> blocks inside a fetched SVG are not executed. Leave it that way for anything untrusted - 'always' and 'once' run whatever the file happens to contain.

Scripts aren't the only vector. Event-handler attributes such as onload and onclick, and href="javascript:..." on <a> elements, are inert to evalScripts but live once injected. For untrusted sources, sanitise the SVG element in beforeInjection, which runs after the fetch and before the element reaches the DOM:

import DOMPurify from 'dompurify'
import { ReactSVG } from 'react-svg'

const Icon = ({ src }) => (
  <ReactSVG
    beforeInjection={(svg) => {
      DOMPurify.sanitize(svg, { IN_PLACE: true })
    }}
    src={src}
  />
)

Sanitising the URL matters too. A javascript: or data:text/html value in src should never reach this component; validate the URL's scheme and origin before passing it in.

Injected content isn't isolated. A <style> element inside an SVG applies to the whole page, so a fetched file can restyle your app through a generic class name like .cls-1, and the last SVG injected wins (#2077). DOMPurify keeps <style> elements, so sanitising doesn't address this. Remove or rewrite them in beforeInjection if the SVGs aren't yours. Note that renumerateIRIElements (on by default) makes id attributes unique, but does nothing for class names.

FAQ

Why are there two wrapping elements?

This module delegates its core behaviour to @tanem/svg-injector, which requires a parent node when swapping in the SVG element. The swap occurs outside of React flow, so we don't want React updates to conflict with the DOM nodes @tanem/svg-injector is managing.

Example output, assuming a div wrapper:

<div>
  <!-- The wrapper, managed by React -->
  <div>
    <!-- The parent node, managed by @tanem/svg-injector -->
    <svg>...</svg>
    <!-- The swapped-in SVG, managed by @tanem/svg-injector -->
  </div>
</div>

See:

Related issues and PRs:

Can I use data URIs or inline SVG strings?

Data URIs yes, inline strings no. data:image/svg+xml URLs are parsed directly with DOMParser and make no network request - see src and the data URL example.

Raw markup passed as src is not supported. If you already hold the SVG as a string - a generated chart, say - parse it with DOMParser and append the result yourself, or render it with dangerouslySetInnerHTML. Both skip the fetch, and the brief flash when react-svg re-injects on a src change. Either way you're inserting markup outside React's escaping, so Security applies.

Contributing

Issues and pull requests are welcome. npm run test:src is the development loop; npm test runs the full gate.

Repo conventions that aren't visible in the code - the PR labels that drive releases, the React version matrix policy, and how the examples/ dependencies are pinned - live in AGENTS.md. Coding agents read it from the repo root, so keep it in sync when a change invalidates something it states.

License

MIT