Why
When using React in conjunction with other JavaScript libraries, it's common to see that React-specific versions of those libraries exist. Regardless of whether they exist to make parts of those libraries available as components, or to aid the developer in making React play nice with a particularly intricate library, I think this is not the case for Chart.js.
Initialization
If we take advantage of React's useRef
hook, we can make use of Chart.js without the need for a made-for-react version of it. The key snippet looks like this:
import React, { useEffect, useRef } from 'react';
import Chartjs from 'chart.js';
const chartConfig = {
type: 'bar',
data: {
// ...
},
options: {
// ...
}
};
const Chart = () => {
const chartContainer = useRef(null);
const [chartInstance, setChartInstance] = useState(null);
useEffect(() => {
if (chartContainer && chartContainer.current) {
const newChartInstance = new Chartjs(chartContainer.current, chartConfig);
setChartInstance(newChartInstance);
}
}, [chartContainer]);
return (
<div>
<canvas ref={chartContainer} />
</div>
);
};
export default Chart;
Chart.js uses the DOM Canvas to render, and the ctx
parameter in new Chartjs(ctx, options)
is a reference to the <canvas />
element where we'll mount our chart.
They key takeaway from this is that the useRef
hook allows us to use an effect to initialize our chart as soon as the DOM object is available, by reacting to changes on the chartContainer
ref variable.
After initialization
On initialization, we're assigning the initialized chart to the chartInstance
state variable so that we can update our chart later, like this:
const updateDataset = (datasetIndex, newData) => {
chartInstance.data.datasets[datasetIndex].data = newData;
chartInstance.update();
};
const onButtonClick = () => {
const data = [1, 2, 3, 4, 5, 6];
updateDataset(0, data);
};
This updates the Chart after the callback for a button click is invoked, but this could also be done inside a useEffect
callback, or really anywhere else where you have access to chartInstance
.
There, short but sweet little tip!
PS. Check out the working version on codesandbox.io!
Discussion (2)
Nice post, ty :)
Thanks mate, great help, short precise and helpful