For those of you unfamiliar with D3, it is a visualization library that is most likely behind any impressive web-based graphics you’ve seen on sites such as the New York Times, FiveThirtyEight or Flowing Data.
It typically requires direct access to the DOM to make its magic happen. This, of course, is in conflict with React and its utilization of the Virtual DOM. I’ll show you an easy way to work around this limitation, and get you back to making those amazing D3 graphics you know and love, within the React ecosystem.
What is D3?
D3 stands for Data Driven Documents. A description of D3 is put best on their website:
D3 helps you bring data to life using HTML, SVG, and CSS. D3’s emphasis on web standards gives you the full capabilities of modern browsers without tying yourself to a proprietary framework, combining powerful visualization components and a data-driven approach to DOM manipulation.
If you’re not familiar with D3 and how it works I’m afraid this article probably isn’t the best place to start. There’s some terrific courses on Udemy that can get you started with D3. I’m purely going to be focusing on how to get D3 playing nicely with React.
React and the Virtual DOM
As mentioned in the introduction, D3 typically works by injecting itself directly into the DOM. React’s Virtual DOM acts as a wedge in this instance as working around it will throw the app’s rendering mechanism off-balance.
Luckily, React has a built-in feature that allows us to utilize third-party libraries that are made to be used with direct DOM manipulation. React Refs to the rescue! I’ll turn to the documentation to back me up:
In the typical React dataflow, props are the only way that parent components interact with their children. To modify a child, you re-render it with new props. However, there are a few cases where you need to imperatively modify a child outside of the typical dataflow. The child to be modified could be an instance of a React component, or it could be a DOM element. For both of these cases, React provides an escape hatch.
A Typical React-D3 Component Structure
We create a React-D3 component by rendering a SVG element with a
ref. The element, in the example below, is passed an argument called
node within the
ref. We then set
this.node, i.e. the definition of the node within the Class context, to be equal to
node. I chose the name node as it follows on from standard data structure conventions but we could have called this whatever we want.
All of the D3 logic sits within the
createChart method. It’s important to call this both in the
componentDidUpdate lifecycle methods. This will allow React to re-render the D3 graphics if the data passed into the component changes with time. All of the D3 code you’d typically write is written within the
createChart method without any further modifications to your workflow.
React and D3 in Action
I can’t really write this up without putting my money where my mouth is. I’ve created a really simple React-D3 component which draws a blue circle using the logic provided above.
For those of you familiar with D3, you’ll see how you can use D3 in React by implementing some very minor tweaks to your typical workflow. There are, however, major possible gains because of how React opens you up to the world of state — something that can take your D3 visualizations to the next level.