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" />
Pros
This method is recommended exclusively for handling large Scalable Vector Graphics (SVG) files.
Cons
There is a delay before it appears on the screen, and styling the SVG is not possible in this scenario.
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>
);
Pros
Easy to implement, customizable styling, and no flickering issues.
Cons
If you use the same SVG in multiple places, it adds unnecessary weight to the DOM, leading to an increase in bundle size, especially when dealing with numerous SVGs in your project.
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
- 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>
- Pre-load the mentioned
sprite.svg
file by adding the following toindex.html
:
<head>
// remaining code
<link rel="preload" as="image/svg+xml" href="/sprite.svg" />
</head>
- Utilize the previously constructed Icon.tsx component by passing the respective name to it.
Code Snippet
src/components/Example.tsx
Details
See Also
- React Code
- React (Tool)
- JavaScript Code
- TypeScript Code
- Development Map of Content
- React Map of Content
- JavaScript Map of Content
- Hyper Text Markup Language (HTML)
- Cascading Style Sheets (CSS)
- Next.js
Appendix
Note created on 2024-05-09 and last modified on 2024-05-09.
Backlinks
LIST FROM [[React - Managing SVGs]] AND -"CHANGELOG" AND -"04-RESOURCES/Code/React/React - Managing SVGs"
(c) No Clocks, LLC | 2024