React for Data Visualization
Student Login
  • Introduction

Full integration components with hooks

The core mental shift with hooks comes in where your D3 code lives 👉 in the main render.

Where we used to spread D3 code around the whole component class, hooks let us do it all in the main render method. Because that's all there is to our component - the main render method.

Anything bound to component lifecycle goes into useEffect, anything we need every time, goes in the function body. When a lot of logic builds up, extract it to a custom hook.

If you're worried about performance or have a large dataset 👉 wrap in useMemo.

Let's build a scatterplot step by step. Because scatterplots let us focus on the React + D3 interaction :)

  1. Render a circle for each datapoint
  2. Use scales to position circles
  3. Add axes
  4. Use a render prop to make datapoint rendering more flexible
  5. Can you make the scatterplot shrink on click?
  6. How about the datapoint expand on mouseover?

My final solution

useMemo is your new best dataviz friend

My favorite hook for making React and D3 work together is useMemo. It's like a combination of useEffect and useState.

Remember how the rest of this course focused on syncing D3's internal state with React's internal state and complications around large datasets and speeding up your D3 code to avoid recomputing on every render?

All that goes away with useMemo – it memoizes values returned from a function and recomputes them when particular props change. Think of it like a cache.

Say you have a D3 linear scale. You want to update its range when your component's width changes.

function MyComponent({ data, width }) {
const scale = useMemo(() =>
d3.scaleLinear()
.domain([0, 1])
.range([0, width])
), [width])
return <g> ... </g>
}

useMemo takes a function that returns a value to be memoized. In this case that's the linear scale.

You create the scale same way you always would. Initiate a scale, set the domain, update the range. No fancypants trickery.

useMemo's second argument works much like useEffect's does: It tells React which values to observe for change. When that value changes, useMemo reruns your function and gets a new scale.

Don't rely on useMemo running only once however. Memoization is meant as a performance optimization, a hint if you will, not as a syntactical guarantee of uniqueness.

Try adding useMemo in your code from before to optimize performance. See what happens if we render thousands of points instead of tens.

Created by Swizec with ❤️