Managing SVGs React Code

Sources:

title: ## Contents 
style: nestedList # TOC style (nestedList|inlineFirstLevel)
minLevel: 1 # Include headings from the specified level
maxLevel: 4 # Include headings up to the specified level
includeLinks: true # Make headings clickable
debugInConsole: false # Print debug info in Obsidian console

Overview

NOTE

When constructing a UI, the significance of SVG cannot be overstated. As the code base expands, the utilization of SVG also grows. In this blog, we will explore the top three methods for rendering SVG and identify the most optimal solution among them.

Initial Approach

Initially, the approach was to use a simple <img> HTML tag:

const ImageSvg = () => <img src="logo.svg" />

Most Common Approach

We’ll craft an SVG component named PlusSVG.tsx, allowing us to conveniently utilize this component in various locations.

// src/svg/PlusSVG.tsx
const PlusSVG = () => (
  <svg viewBox="0 0 50 50">
    <path d="M 25 2 C 12.309295 2 2 12.309295 2 25 C 2 37.690705 12.309295 48 25 48 C 37.690705 48 48 37.690705 48 25 C 48 12.309295 37.690705 2 25 2 z M 25 4 C 36.609824 4 46 13.390176 46 25 C 46 36.609824 36.609824 46 25 46 C 13.390176 46 4 36.609824 4 25 C 4 13.390176 13.390176 4 25 4 z M 24 13 L 24 24 L 13 24 L 13 26 L 24 26 L 24 37 L 26 37 L 26 26 L 37 26 L 37 24 L 26 24 L 26 13 L 24 13 z"></path>
  </svg>
);

We will render the previously created component in the relevant sections as needed.

// src/App.tsx
import PlusSVG from "@/svg/PlusSvg"
 
const App = () => (
  <div>
    <PlusSVG />
  </div>
);

Most Effective Method: SVG Sprites

Creating a reusable “Icon” component for rendering SVG icons.

// src/components/Icon.tsx
import { SVGProps } from "react";
 
type ISvgPropType = {
iconName: string;
} & SVGProps<SVGSVGElement>;
 
const Icon = ({ iconName, ...props }: ISvgPropType) => (
<svg {...props} >
    <use href={`#${name}`} />
</svg>
);
 
export default Icon;

Developing a “Sprite” component to handle all SVG icons.

// src/components/SVGSprite.tsx
const SVGSprite = () => (
  <svg xmlns="http://www.w3.org/2000/svg">
      <defs>
      <symbol id="plus" viewBox="0 0 24 24">
          <path d="M 25 2 C 12.309295 2 2 12.309295 2 25 C 2 37.690705 12.309295 48 25 48 C 37.690705 48 48 37.690705 48 25 C 48 12.309295 37.690705 2 25 2 z M 25 4 C 36.609824 4 46 13.390176 46 25 C 46 36.609824 36.609824 46 25 46 C 13.390176 46 4 36.609824 4 25 C 4 13.390176 13.390176 4 25 4 z M 24 13 L 24 24 L 13 24 L 13 26 L 24 26 L 24 37 L 26 37 L 26 26 L 37 26 L 37 24 L 26 24 L 26 13 L 24 13 z"></path>
      </symbol>
      <symbol id="heart" viewBox="0 0 24 24">
          <path d="M 25 2 C 12.309295 2 2 12.309295 2 25 C 2 37.690705 12.309295 48 25 48 C 37.690705 48 48 37.690705 48 25 C 48 12.309295 37.690705 2 25 2 z M 25 4 C 36.609824 4 46 13.390176 46 25 C 46 36.609824 36.609824 46 25 46 C 13.390176 46 4 36.609824 4 25 C 4 13.390176 13.390176 4 25 4 z M 24 13 L 24 24 L 13 24 L 13 26 L 24 26 L 24 37 L 26 37 L 26 26 L 37 26 L 37 24 L 26 24 L 26 13 L 24 13 z"></path>
      </symbol>
      </defs>
  </svg>
);

Render the SpriteSvg in the App component

// src/App.tsx
import SpriteSvg from "@/SpriteSvg";
 
const App = () => (
  <div>
    // remaining code
    <SpriteSvg />
  </div>
);

How to use:

// src/components/Component.tsx
import Icon from "@/Icon";
 
const App = () => (
  <div>
    <Icon name="plus" />
  </div>
);

How to Handle Large Sprites in Large Projects

  1. Create an SVG file for sprites and place it within the public folder.
<!-- sprites.svg -->
<svg xmlns="http://www.w3.org/2000/svg">
  <defs>
    <symbol id="plus" viewBox="0 0 24 24">
      <path
        d="M 25 2 C 12.309295 2 2 12.309295 2 25 C 2 37.690705 12.309295 48 25 48 C 37.690705 48 48 37.690705 48 25 C 48 12.309295 37.690705 2 25 2 z M 25 4 C 36.609824 4 46 13.390176 46 25 C 46 36.609824 36.609824 46 25 46 C 13.390176 46 4 36.609824 4 25 C 4 13.390176 13.390176 4 25 4 z M 24 13 L 24 24 L 13 24 L 13 26 L 24 26 L 24 37 L 26 37 L 26 26 L 37 26 L 37 24 L 26 24 L 26 13 L 24 13 z"
      ></path>
    </symbol>
    <symbol id="heart" viewBox="0 0 24 24">
      <path
        d="M 25 2 C 12.309295 2 2 12.309295 2 25 C 2 37.690705 12.309295 48 25 48 C 37.690705 48 48 37.690705 48 25 C 48 12.309295 37.690705 2 25 2 z M 25 4 C 36.609824 4 46 13.390176 46 25 C 46 36.609824 36.609824 46 25 46 C 13.390176 46 4 36.609824 4 25 C 4 13.390176 13.390176 4 25 4 z M 24 13 L 24 24 L 13 24 L 13 26 L 24 26 L 24 37 L 26 37 L 26 26 L 37 26 L 37 24 L 26 24 L 26 13 L 24 13 z"
      ></path>
    </symbol>
  </defs>
</svg>
  1. Pre-load the mentioned sprite.svg file by adding the following to index.html:
<head>
  // remaining code
  <link rel="preload" as="image/svg+xml" href="/sprite.svg" />
</head>
  1. Utilize the previously constructed Icon.tsx component by passing the respective name to it.

Code Snippet

  • src/components/Example.tsx
 

Details

See Also


Appendix

Note created on 2024-05-09 and last modified on 2024-05-09.

LIST FROM [[React - Managing SVGs]] AND -"CHANGELOG" AND -"04-RESOURCES/Code/React/React - Managing SVGs"

(c) No Clocks, LLC | 2024