SVG is a vector graph based on an image format based on XML syntax. And no matter how much magnification will not distortion. Since ICONS are needed in the project. However, the process of using SVG in the React version of the billing project is not very smooth… Anyway, the final function is implemented

Use as a picture

  • Import:
import x from 'label.svg'
Copy the code
  • use
<img src={x} alt=""/>
Copy the code

disadvantages

  • We can’t do things like set the color of the image
  • Duplicate SVG code needs to be copied and pasted, which is a huge amount of maintenance work.

So why not componentize? This is done using SVG with the use tag

Use as an SVG Symbol

The React application requires a loader but does not have a webPack configuration file. Therefore, you need to customize the webPack

Custom webpack

  1. Run YARN eject to get the WebPack configuration
  2. Install svG-sprite-loader: yarn add –dev svg-sprite-loader
  3. Install svGo-loader: yarn add –dev svgo-loader
  4. Configure two loaders in the config/webpack.config.js file
{
     test: /\.svg$/,
      use: [
          	{loader: 'svg-sprite-loader', options: {}},
          	{loader: 'svgo-loader', 
                 options: {plugins:[{removeAttrs: {attrs: 'fill'}}]}
             }
            ]
 },
Copy the code

After installation, an error may be reported. If the problem is minor, operate as prompted.

use

SVG contains the use tag, with id corresponding to # plus the name of the SVG file

<svg><use xlinkHref=id/></svg>
Copy the code

Here’s an example:

Use xlinkHref='#label'/></ SVG >Copy the code

Picture not shown?? Triggered TreeShaking

TreeShaking

Variables that are not used are deleted by default

  • You can see that there is no obvious use of X, just importing SVG
  • So it’s TreeShanking
  • To prevent imported SVG from being TreeShaking, use require instead of import
 require('label.svg')
 <svg><use xlinkHref='#label'/></svg>
Copy the code

To do this every time you use SVG, why not wrap code that uses SVG into components?

Create Icon components (componentized emphasis!)

  • Import all SVG at once

  • In the ICONS directory, the filename is used as the ID to refer to any component

Icon.tsx

import React from 'react'; let importAll = (requireContext: __WebpackModuleApi.RequireContext) => requireContext.keys().forEach(requireContext); try {importAll(require.context('icons', true, /\.svg$/)); } catch (error) {console.log(error); } type Props = { name: string } & React.SVGAttributes<SVGElement> const Icon = (props: Props) => { return ( <svg> <use xlinkHref={'#' + props.name}/> </svg> ); }; export default Icon;Copy the code

When SVG is needed, it would be convenient to reference the Icon component directly and pass the SVG file name to the component

 <Icon name="left"/>
Copy the code

Failed to import all SVG code at once:

Install: yarn add — dev@types /[email protected]

What exactly does loader do?

svg-sprite-loader

  • Svg-sprite-loader finds an SVG tag, changes the SVG to a symbol, then coats the symbol with an SVG tag, and finally puts the SVG inside the body.
  • Why a layer of SVG? Because there could be a lot of SVG
  • SVG can be used with the use tag

svgo-loader

When SVG defaults to using the fills attribute to set colors, it will not be possible to swap colors

  • Configure svGo-Loader to remove the inherent FILL attribute of SVG, so that the SVG color can be customized by setting fill