Using React with SVG images
Perhaps the biggest selling point for Facebook's UI library, React is reusability. Build a component once, and you can import it in multiple places across your project, or distribute it for the community's benefit.
Reusability makes React an excellent library for creating HTML components. But what if we used React to create SVG components?
I used this technique to build the Search box component for Vets.gov. Turning the magnifying glass icon into a React component made sense; it's used twice just for the Search box. And by using SVG inline, we can use CSS to change the color of the icon instead of using multiple icon files.
Things to consider
When creating the IconSearch and IconHelp components, I considered how they might be used throughout the site.
- Would it always be the same color? (No.)
- Could they ever become the child of a clickable element, such as
a
,button
, orlabel
? (Yes. Always.) - Might it ever be used as a visual replacement for text? (Yes.)
The answers to those questions determined which elements and attributes would become props
and which could remain as markup, as shown below.
class IconSearch extends React.Component {
render() {
let svgTitle;
if (this.props.title) {
svgTitle = <title>{this.props.title}</title>;
}
return (
<svg width="24" height="24" viewBox="0 0 216 146"
pointerEvents="none"
className={this.props.cssClass}
id={this.props.id}>
{svgTitle}
<path fill={this.props.color}
d="M172.77 123.025L144.825 95.08c6.735-9.722z..."/>
</svg>
);
}
}
In this case:
- Defining
fill
andcssClass
properties (props
) means the icon can be displayed in any color. - Adding a
pointerEvents
attribute prevents the icon from receiving mouse events. - Defining a
title
property lets us include descriptive text for AT users when necessary, and eliminate it when it's redundant.
Prepare your SVG for React and JSX
Now you can't just copy-and-paste an SVG document into a React/JSX file and have it work. JSX looks like XML, but it isn't XML. We'll need to make our SVG document conform to JSX rules by taking the following steps.
- Remove the
<? xml ?>
prolog. - Remove
<!-- comments -->
. - Remove the
xmlns:xlink
attribute from the opening<svg>
tag. - Change hyphenated SVG attributes to be camelCase instead. For example,
stroke-width
should becomestrokeWidth
andfill-rule
needs to befillRule
. - Use
/>
instead of closing tags, e.g.<rect />
not<rect></rect>
If you forget to do any of these things, don't worry. React will log an error message to the console (you're using the React Developer Tools Extension, yes?).
If that's too much work for you, you can also use svgr, a Node-based tool that converts SVG files to React components.
These are really simple examples of course. SVG React components are only limited by the features of SVG. A more complex component might use React to create a reusable SVG graph, pie chart or map.