chartEl
is the ref object, not the element. So you would need to access chartEl.current
.
But you don't want to be storing the ref to your div
as chartEl
anyways. A div
does not have properties like resize()
and setOption()
. Those only make sense once you have a chart instance.
The flow of actions here is honestly really tricky as you can't really use refs as a useEffect
dependency.
I actually think that this is a good use case for callback refs, where you define the ref as a function of the element.
But then I am using useRef
instead of useState
to store the chart object itself because state should be immutable and the chart object is mutable.
import React, { useRef, useEffect } from "react";
import { init, ECharts } from "echarts";
interface EChartProps {
// what are these types really?
option: any;
config?: any;
resize?: any;
}
function EChart({ option, config, resize }: EChartProps) {
// using a ref instead of state to store the chart because it is mutable
const chart = useRef<ECharts>();
// use a callback ref to initialize the chart
const containerRef = (element: HTMLDivElement | null) => {
// ignore if already set
if (element && !chart.current) {
// create a chart and set properties
const newChart = init(element);
newChart.setOption(option);
newChart.resize();
// store to the chart ref
chart.current = newChart;
}
};
useEffect(() => {
// refresh if option changes
chart.current?.setOption(option);
}, [option]);
return (
<div
className="chart"
// needs some minimum height or else it is 0
style={{ height: "100vw" }}
ref={containerRef}
></div>
);
}
export default () => {
return (
<EChart
// example data from https://echarts.apache.org/examples/en/editor.html?c=line-simple
option={{
xAxis: {
type: "category",
data: ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"]
},
yAxis: {
type: "value"
},
series: [
{
data: [150, 230, 224, 218, 135, 147, 260],
type: "line"
}
]
}}
/>
);
};
Code Sandbox Link