How to import an entire folder of SVG images (or how to dynamically load them) into a React Web application?

I have a component that accepts: itemName and spills out an html package containing an image. The image for each beam is different.

Here is what I have:

import React, { Component } from 'react'; import { NavLink } from 'react-router-dom'; import SVGInline from "react-svg-inline"; export default (props) => ( <NavLink className="hex" activeClassName="active" to={'/hex/' + props.itemName}> {React.createElement(SVGInline, {svg: props.itemName})} </NavLink> ) 

How can I make this component work?

I know that if I just imported all my images explicitly, I could just call my images like this ...

 import SVGInline from "react-svg-inline"; import SASSSVG from "./images/sass.svg"; <NavLink className="hex" activeClassName="active" to="/hex/sass"><SVGInline svg={ SASSSVG } /></NavLink> 

This will work, but since I need to enable ~ 60 svgs, it will add a lot of redundant code.

Also, I found this code in this question ...

 import * as IconID from './icons'; 

But this does not work (it was a question, not an answer), and the answer was too nonspecific to answer the question I ask.

I also found this question , but again there is an answer (although not approved) that has more questions than answers. So, after setting the reaction-svg, I set up a test to see if the answer works like that ...

 import React, { Component } from 'react'; import ReactDOM from 'react-dom' import { NavLink } from 'react-router-dom'; import ReactSVG from 'react-svg' export default (props) => ( <NavLink className="hex" activeClassName="active" to={'/hex/' + props.itemName}> <ReactSVG path={"images/" + props.itemName + ".svg"} callback={svg => console.log(svg)} className="example" /> </NavLink> ) 

But, as the OP asked this question, the page cannot find my SVG even after copying the entire image folder to my build folder. I also tried "./images/"

It seems to me that I just missed the last key piece of information, and after I looked for the last day, I hoped that someone would be able to determine which part I was missing.

+8
javascript import dynamic reactjs svg
source share
4 answers

If you are using React, I suspect you are also using webpack. You can use require.context instead of es6 import , and webpack will allow it for you to create.

This first line is the import. We store all files ending with .svg in the images folder. Change the second parameter to false if you do not want to scan the recursive folder.

 const svgs = require.context('./images', true, /\.svg$/) 

This gives us a function with the keys property and id property. We can pass the file path to return the image. The keys property gives us a list of valid file paths. The id property is the id of the webpack module. In this example, it would be easier to see: SurviveJS Webpack Dynamic Loading

This api is limited as well as possibly unintuitive, so you will most likely want to convert it to a more general javascript data structure to make things easier. Here are 3 examples that may be helpful.


Create an array of files only. You can get the index number from the keys array if you need to access the image along the way.

 const svgs = require.context('./images', true, /\.svg$/) const keys = svgs.keys() const svgsArray = keys.map(key => svgs(key)) 

Create an array of objects, each of which will be {path, file} for 1 image

 const svgs = require.context('./images', true, /\.svg$/) const svgsObjArray = svgs.keys() .map(key => { path: key, file: svg(key), }) 

Create an object where the path is the key to the corresponding file.

 const svgs = require.context('./images', true, /\.svg$/) const svgsObj = svgs.keys() .reduce((images, key) => { images[key] = svgs(key) return images }, {}) 
+3
source share

Instead of several SVG files, you can use one SVG sprite.

SVG sprite can be generated from the directory of SVG files using svg-sprite-generator :

 svg-sprite-generate -d images -o images/sprite.svg 

Then use it as follows:

 import React from 'react'; import { NavLink } from 'react-router-dom'; import sprite from './images/sprite.svg'; export default (props) => ( <NavLink className="hex" activeClassName="active" to={'/hex/' + props.itemName}> <svg xmlns="http://www.w3.org/2000/svg" width="30" height="30"> <use xlinkHref={`${sprite}#${props.itemName}`} /> </svg> </NavLink> ) 
+3
source share

You can simply make a function that takes the name parameter (your svg icon name) and returns your svg code.

import React from 'react' export function getIcon(name){ switch(name) { case 'back': return ( // your svg code here <svg></svg> ) } }

And then you can import it anywhere and just call it with the icon you want.

 import { getIcon } from './utils' render() { return ( <div> <span>{ getIcon('back') }</span> </div> ) } 
+1
source share

A better way is to use a node module such as [SVG to React Loader] ( https://github.com/jhamlet/svg-react-loader )

+1
source share

All Articles