Let's make the ultimate icon component in React.
We want to build something that as reusable and flexible as possible.
Let's do it.
Since this is React component, it only makes sense to start with Create React App.
This will take a minute to run.
Let's start cleaning up the pieces a little bit.
Within App.js we can remove all the content. Eventually, our icon will be in the same location as the React logo.
In App.css let's clean that file up, too. We can remove all the styles related to the spinning animation and the text link. Should look like this:
First, let's talk about how we want this component to work:
Now, let's create a folder, called components. Inside, let's create another folder called Icons. We'll keep everything related to our component here.
Now, let's create a file named index.js.
Inside, I'm going to type . I have an extension within my VS Code editor that will use this snippet to stub out a functional react component.
I'm going to turn this a named export. Why? Because consistency prevents errors. I won't have to think twice about whether a component is a named export or a default export, because everything is a named export.
I'm going to just add text "Icon" between the tags to make sure that it's loading correctly within our App.
Within App.js I'm going to import our new file and replace the tag with our component:
Great! Now, let's create a few icons.
Within the Components/Icons folder, let's create three new files: Facebook.js, Instagram.js, and Twitter.js.
As you might have guessed, we're going to add SVG icons to each of these files.
I'm going to jump over to Figma. The trick is that each icon has the same size bounding box. In this case, all our icons are going to be 25 x 25.
Within Figma, I can select each icon, then click on the + in the Export section, select SVG, and click on the Export button. The file will download to my desktop.
I'm going to do this for Facebook, Instagram, and Twitter.
Now, I'm going to grab the Facebook.svg and open it directly within VS Code. You'll notice it looks like a bunch of gobbly gook. That's OK. I'm going to copy it and open Facebook.js.
I'm going to use that shortcut again.
We're going to change this to a named export
and paste the code from our Clipboard into our statement.
There are a few properties here that we want to be dynamic. We can pass those in as props:
I'm going to add
and I want to remove any inline references to . We want to be able to control the color with CSS and if they're inline, that will take precedence over our CSS.
You may notice that when I hit save, the code automatically re-formats itself. I have an extension within VS Code called Prettier that does that for me. I'll include a link in the description below.
Now, let's do the same thing for our Twitter and Instagram icons.
Let's copy and paste the code from Facebook.js inito Twitter.js and Instagram.js. I'm going to change the name of the component and the export.
Now, I'm going to open Twitter.svg and copy the code and paste it into Twitter.js, overwriting the Facebook SVG.
I'll plug in the prop values for and and create one for .
Remove any references to .
Last one: Instagram. Same old story.
Now, let's jump back to our Icon/index.js file. This is where we'll start to tie all these pieces together.
At the top, we want to import all of the icons that we've created:
Within the component, we want to be able to pass in the name of the icon and have it return the correct icon component.
Let's accept our props:
If we were right to write this as an if / else conditional, this is what our code would look like:
This line says when we pass in as a prop and make it lowercase. — this way our code will work regardless of whether we pass in a as all caps or all lowercase letters. — if I pass in Facebook, return the Facebook component.
The is called a spread. It just takes all the props that we pass in and passes it straight on to the component. — So, the , , and props that we set up within our Facebook.js component — it will pass all those props along without us having to define everything.
Now, to write the
Then, at the end, we want to say: "If you still didn't find what we're looking for, just give us an empty "
Anytime you start to see yourself repeating code, that's a "code smell" — it's a good opportunity to refactor. You'll probably notice that we're using that a lot. And really, we keep checking the same thing. A statement is perfect for this scenario.
Here's what it looks like:
The is what we're testing against each time. Then, below, we have a "case" statement. If our is equivalent to then it will run the code.
So, we just want to turn each of those conditional lines into a statement:
Now, for our in our conditional statement. It's the if nothing else is true, it will run:
Now, with that setup, let's jump back over to our App.js and pass in a name for the icon we want to display:
Aswesome, it worked!
We just need to reign in the size and the change the color. Remember, our width and height are props we can pass in. Let's jump back over to App.js and update our component:
Now, we just want to change the color. Within App.css we can add this block:
When you're targeting the color of an svg, you use instead of color. You could use whatever color you want:
Save. See it update.
Save it update.
Or, a little trick I like to use is when we want it to adobe the text color of the parent. You can use .
I'll add the text, "Facebook", below our icon to show you what I mean.
Here, the text is white because of property on
We can have our icon inherit that color by changing to .
Receive a weekly email of the Internet's best from articles, to tutorials, to pro tips.