useECharts
React hook that owns the chart lifecycle while you own the container markup
Overview
useECharts is a hook primitive that drives the same lifecycle as <EChartsReact> (init, option updates, event binding, resize, teardown) but lets you render the container <div>. Reach for it when the component’s fixed container gets in the way — for example, when nesting the chart in a styled card with a toolbar, swapping in a skeleton loader, or composing the chart with surrounding layout you’d rather control directly.
import { useECharts } from 'react-echarts-library'; // full bundle
import { useECharts } from 'react-echarts-library/core'; // tree-shakeable
Added in v1.4.0.
Signature
function useECharts(
echarts: EChartsCore,
options: UseEChartsOptions
): {
containerRef: (node: HTMLDivElement | null) => void;
getInstance: () => EChartsType | null;
};
| Argument | Type | Description |
|---|---|---|
echarts | EChartsCore | The echarts instance. From the full bundle, pass echarts (it satisfies the shape). From react-echarts-library/core, pass your tree-shaken echarts/core import. |
options | UseEChartsOptions | Same shape as EChartsReactProps minus the container-level props (style, className, HTML attrs) — those belong on your own div. |
UseEChartsOptions accepts: option, theme, opts, onEvents, notMerge, replaceMerge, lazyUpdate, showLoading, loadingOption, shouldSetOption, autoResize, onChartReady. See the Props Reference for each field.
Return value
| Field | Type | Description |
|---|---|---|
containerRef | (node) => void | Callback ref. Attach to your container <div>. The hook initializes the chart when the node mounts and disposes on unmount. |
getInstance | () => ECharts | null | Imperative accessor for the underlying ECharts instance. Returns null before mount and after unmount. |
Minimal Usage
import { useECharts } from 'react-echarts-library/core';
import * as echarts from 'echarts/core';
import { BarChart } from 'echarts/charts';
import { GridComponent, TooltipComponent } from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([BarChart, GridComponent, TooltipComponent, CanvasRenderer]);
function MyChart() {
const { containerRef } = useECharts(echarts, {
option: {
xAxis: { type: 'category', data: ['A', 'B', 'C'] },
yAxis: { type: 'value' },
series: [{ type: 'bar', data: [10, 20, 30] }],
},
});
return <div ref={containerRef} style={{ height: 320 }} />;
}
Imperative Toolbar
Use getInstance to dispatch ECharts actions from your own UI:
import { useECharts, exportToPNG } from 'react-echarts-library';
import * as echarts from 'echarts';
function ChartCard() {
const { containerRef, getInstance } = useECharts(echarts, { option });
const handleZoomIn = () => {
getInstance()?.dispatchAction({ type: 'dataZoom', start: 20, end: 80 });
};
const handleExport = () => {
const chart = getInstance();
if (chart) exportToPNG(chart, { filename: 'chart.png' });
};
return (
<section className="card">
<header className="card-header">
<h3>Quarterly Revenue</h3>
<div className="card-actions">
<button onClick={handleZoomIn}>Focus middle</button>
<button onClick={handleExport}>Download PNG</button>
</div>
</header>
<div ref={containerRef} style={{ height: 320 }} />
</section>
);
}
Loading Skeleton Swap
The hook returns a callback ref, so you can mount the chart only after data is ready and render a skeleton in its place beforehand:
function AsyncChart({ data, isLoading }) {
const { containerRef } = useECharts(echarts, {
option: { /* derived from data */ },
});
if (isLoading) {
return <div className="skeleton" style={{ height: 320 }} />;
}
return <div ref={containerRef} style={{ height: 320 }} />;
}
Reacting to External State
Combine with useChartTheme to react to OS dark-mode changes, or any other React state, without re-implementing the lifecycle:
import { useECharts, useChartTheme } from 'react-echarts-library';
import * as echarts from 'echarts';
function ThemedChart({ data }) {
const theme = useChartTheme();
const { containerRef } = useECharts(echarts, {
theme,
option: {
xAxis: { type: 'category', data: data.labels },
yAxis: { type: 'value' },
series: [{ type: 'line', data: data.values }],
},
});
return <div ref={containerRef} style={{ height: 320 }} />;
}
Typed Events
Pair with EChartsEventsMap for IDE completion on event names:
import { useECharts } from 'react-echarts-library';
import type { EChartsEventsMap } from 'react-echarts-library';
const handlers: EChartsEventsMap = {
click: (params) => console.log('clicked:', params),
legendselectchanged: (params) => console.log('legend:', params),
};
function TypedChart() {
const { containerRef } = useECharts(echarts, { option, onEvents: handlers });
return <div ref={containerRef} style={{ height: 320 }} />;
}
When to Use the Hook vs the Component
| Use case | Recommended |
|---|---|
| Drop a chart into a layout | <EChartsReact> / <EChartsCore> |
| Render a styled card around the chart | useECharts |
| Swap a skeleton in for the chart container | useECharts |
| Position a toolbar that talks to the instance | Either — useECharts is one less ref hop |
| Share the lifecycle across non-chart UI | useECharts |
The component is implemented on top of the hook, so neither path costs more than the other at runtime.
See Also
- EChartsReact — full-bundle component built on this hook
- EChartsCore — tree-shakeable component built on this hook
- Utilities —
exportToPNG,exportToSVG,useChartTheme - Event Handling — including typed event helpers