React Higher-Order Component for SVG icons

Recently I’ve started to learn Functional Programming and found its basic implementation in React. Let’s take a look what benefits we can get from functional composing in a real life React app.


It’s a great idea to use SVG icons as React components in your app. You can just name them this way <MyIcon width=20 height=20 fill=‘#ccc’ />. Then a component’s code will look like:

export default createClass({
render() {
return (
<svg // you can add as many props, as you needed
viewBox={this.props.viewBox}
width={this.props.width}
height={this.props.height}
fill={this.props.fill}
>
<path d="..." fillRule="evenodd" />
</svg>
);
},
});

Great, it works perfectly, you can apply any classes, change size and other stuff by props. But every time when you create a new Icon, you will duplicate <svg> code and props validation. Once you’ve realized it, it’s time to create a higher-order component, which will take a response for repeating code.

Let’s repeat what HOC is:

A higher-order component is just a function that takes an existing component and returns another component that wraps it.

Here we go, our higher-order component for SVG icons:

const createSVG = (Icon) => createClass({
render() {
const {classes, fill, height, width, viewBox} = this.props;
return (
<svg
className={classes}
fill={fill}
height={height}
width={width}
viewBox={viewBox}
>
<Icon />
</svg>
);
},
});
export default createSVG;

It’s an arrow function, which takes an Icon component (within all Icon’s props) as an argument and returns new React Class, where we have Icon component itself wrapped by <svg> tag with the proper attributes.

Now we can declare our Icon component:

import createSVG from '../createSVG';
const Icon = () => <path d="..." fillRule="evenodd" />;
export default createSVG(Icon);

Looks better now, right?


Let’s recap how we did our component better!

We are composing our Icon component with a higher-order component createSVG, by calling createSVG with Icon component as an argument.

export default createSVG(Icon);

The createSVG is a simple arrow function, which returns new React Class, where all Icon’s state and props are scoped, so we can manipulate them as we wish.

const createSVG = (Icon) => createClass({

That’s how we can reuse code and simplify our components with a functional programming approach.