DEV Community

loading...
Cover image for How to create an extremely reusable Icon component with react-svg

How to create an extremely reusable Icon component with react-svg

vtrpldn profile image Vitor Paladini Originally published at paladini.dev ใƒปUpdated on ใƒป3 min read

SVG can be super-duper fast and accessible you know that.

And the coolest thing about SVG in webdev is that CSS simply works with it, so you can do stuff like:

path {
  fill: red;
}
Enter fullscreen mode Exit fullscreen mode

and bam, your icon is red.

Need it to be bigger or smaller? Well, the S on SVG literally stands for "scalable", so you can just go ahead and pow make your icons as big as your browser can handle.

svg {
  width: 33554400px;
  height: 33554400px;
}
Enter fullscreen mode Exit fullscreen mode

However, we might have a problem here, this post is about React but individually importing SVG files in React is a pain... ๐Ÿ˜ฉ

There's a better way

You can leverage the CSS styling features of SVG with React components by using a library called react-svg. This library works by fetching, caching and inlining your SVG icons so you only need to worry about styling them.

Here's the step by step guide on how to create an Icon component that, trust me, is a real pleasure to use.

1 - Create an /icons folder and stuff it with all your favorite icons

2 - Create an Icon component that wraps ReactSVG:

import React from "react";
import ReactSVG from "react-svg";

const Icon = (props) => {
  return <ReactSVG src="YOUR_PATH/icons/${props.name}.svg" />;
}

export default Icon;
Enter fullscreen mode Exit fullscreen mode

3 - Import your Icon component and use it like so:

import React from "react";
import Icon from "./Icon";

const IconList = () {
  return (
    <div>
      <Icon name="user" />
      <Icon name="calendar" />
      <Icon name="phone" />
      <Icon name="email" />
    </div>
  );
}

export default IconList;
Enter fullscreen mode Exit fullscreen mode

Can you see the beauty of it? No more fumbling with icon imports every time you need a new icon. Just add the file to the icon folder, pass its name as a prop to your brand new Icon component and call it a day.

Now, let's go a bit further with this Icon component thingy and make it even more useful.

Give it some style

Did you see how we are using the name prop to fetch the right icon file? We can do the same thing for picking the right color and size of that icon.

All we need is a CSS-in-JS library to act as a glue between our SVG files and our Icon component, we are using Styled Components in the example below but any other library would serve.

Here, take a look. The embed space is pretty limited so feel free to click the "Open Sandbox" button and play with it for a while, just remember to come back. ๐Ÿ™‚

Pretty nice, huh? What I like the most about this approach is that after some initial setup, adding a new icon is as simple as dragging the SVG file to the icon folder. And being able to style it directly in the component props is definitely a plus.

So that's it! Thanks Harpal Singh on Unsplash for the cover photo.

If you have any questions about the example please share it in the comments!


Hey, let's connect ๐Ÿ‘‹

Follow me on Twitter and let me know you liked this article!

And if you really liked it, make sure to share it with your friends, that'll help me a lot ๐Ÿ˜„

Discussion (8)

pic
Editor guide
Collapse
bera5186 profile image
Rahul Bera

Was looking for this from long ago ๐Ÿ˜

Collapse
jfbrennan profile image
Jordan Brennan • Edited

"extremely reusable" and "React" is a contradiction though because it's only usable in a React stack. React, although popular, can't come close to the level of reusability a standards-based solution like custom HTML tags or Custom Elements provides. React, Vue, Riot, etc. are wonderful for structuring your app and managing state changes, but little components like icons are best done with simple, lightweight solutions that aren't tied to a framework.

Collapse
vtrpldn profile image
Vitor Paladini Author

Hey, Jordan. I'm assuming in this article that the reader is already working on a React environment, but your comment made me realize that I should have made that more clear. Thanks for the feedback!

By no means anyone should import React exclusively to create a single icon component, you're absolutely right about that. But in the React context, I'd say these Icons are indeed very much reusable.

Collapse
z2lai profile image
z2lai

How does this compare to using SVGR that's built-in with create react app v2. You can import the svg file as a React component in one line:


import { ReactComponent as Icon } from '. /icons/icon.svg'
Collapse
vtrpldn profile image
Vitor Paladini Author

react-svg lets you dynamically import SVG files so you can spec the SVG file name in the Icon name prop and it'll do the rest :)

Collapse
z2lai profile image
z2lai

Oh right, that's an excellent benefit. Now the post title makes sense :D. Thanks a lot!

Thread Thread
vtrpldn profile image
Vitor Paladini Author

Glad I could help!

Collapse
hemant profile image
Hemant Joshi ๐Ÿ˜ผ

WOW, Thank you Vitor...