Libraries for charts, maps, and editors manage their own DOM. React cannot render them declaratively, so you give the library a container element and drive it imperatively through a ref and an Effect. This article uses Chart.js as the example. The same approach works for any library with a constructor and a destroy method.
The integration pattern
The pattern has three parts. Point a ref at a container element, create the library instance in an Effect after React commits, and destroy it in the cleanup. It is the same container-ref idea used to measure DOM elements, except the library owns the node.
Create the container
Attach a ref to a canvas, div, or other element the library will manage.
Initialize in an Effect
Run the Effect after commit and pass the node to the library constructor.
Clean up
Return a function that calls the library's destroy or dispose method.
A Chart.js example
Install Chart.js, then create a component that owns a canvas. The Effect builds the chart and the cleanup destroys it.
import { useRef, useEffect } from "react";
import Chart from "chart.js/auto";
function BarChart({ labels, values }) {
const canvasRef = useRef(null);
useEffect(() => {
const chart = new Chart(canvasRef.current, {
type: "bar",
data: { labels, datasets: [{ label: "Sales", data: values }] },
});
return () => chart.destroy();
}, [labels, values]);The Effect creates the chart after the canvas commits. Passing labels and values as dependencies recreates the chart whenever the data changes.
return <canvas ref={canvasRef} />;
}The component renders a canvas that Chart.js draws into. The canvas stays empty until the Effect runs, so the chart appears only after commit. When the component unmounts, the cleanup calls destroy, which removes the chart and frees its resources.
Why cleanup matters
Without destroy, the chart keeps running after unmount and can leak canvases or event listeners. Leaked resources keep running after the component is gone, which can slow the page and cause duplicate updates.
Strict Mode mounts, unmounts, and remounts once in development, so the create and destroy cycle runs twice. That double run is expected and verifies that your cleanup is correct.
Recreate only when the data changes
The dependency array controls when the Effect re-runs. Include every reactive value the Effect reads, such as props and state used to build the chart.
Omitting a dependency leaves the chart showing stale data, while an empty array builds the chart once and never updates it. The container ref itself never goes in the array, because React keeps the same ref object across renders. React runs the cleanup before the next setup, so the old chart is destroyed and replaced rather than duplicated.
What to learn next
The same ref and Effect pairing appears when you measure your own DOM. Continue with common React ref errors to catch the mistakes that break this pattern.
Rune AI
Key Insights
- Point a ref at a container element for the library.
- Create the library instance in an Effect after commit.
- Destroy the instance in the Effect cleanup.
- Recreate on dependency changes by listing props in the array.
- Strict Mode runs the create and destroy cycle twice in development.
Frequently Asked Questions
Why initialize a library in an Effect instead of during render?
Why destroy the library in cleanup?
What should go in the dependency array?
Conclusion
Integrate a third-party DOM library by giving it a container ref, creating the instance in an Effect after commit, and destroying it in cleanup. List the data the Effect reads in the dependency array.
More in this topic
How to Build a Dropdown Menu in React
Build a React dropdown menu with the ARIA menu button pattern. Handle open and close, keyboard arrows, and clicks outside the menu.
How to Animate React Components with Motion
Animate React components with the Motion library. Set up motion, add enter, hover, and exit animations, and respect reduced motion.
Headless UI Components Explained: Logic Without Locked Styling
Understand headless UI components and how libraries like Radix give you unstyled, accessible behavior that you style yourself.