//index.tsx

import React, { useEffect, useRef, useState } from "react";
import * as echarts from "echarts";
import useEchartResizer from "./useEchartResizer";
export interface BaseChartProps {
    options: echarts.EChartsOption;
}

const Echart: React.FC<BaseChartProps> = ({ options }) => {
    const chartRef = useRef<HTMLDivElement>(null);
    useEchartResizer(chartRef);
    let myChart: any = null;
    /**
     * @description: resize
     * @return {*}
     */
    const handleResize = () => {
        myChart?.resize();
    };
    /**
     * @description: 初始化
     * @return {*}
     */
    const initChart = () => {
        window.removeEventListener("resize", handleResize);
        myChart?.dispose();
        const renderedInstance = echarts.getInstanceByDom(chartRef?.current);
        if (renderedInstance) {
            myChart = renderedInstance;
        } else {
            myChart = echarts?.init(chartRef?.current as HTMLElement);
        }
        myChart?.setOption(options, true);
        window.addEventListener("resize", handleResize);
    };

    useEffect(() => {
        initChart();
        return () => {};
    }, [options]);

    return <div ref={chartRef} style={{ height: "100%", width: "100%" }} />;
};
export default Echart;

  

//useEchartResizer.ts

import useComponentSize from "./useComponentSize";
import * as echarts from "echarts";
import React, { useEffect } from "react";

const useEchartResizer = (chartRef: React.MutableRefObject<HTMLDivElement>) => {
    const size = useComponentSize(chartRef);

    useEffect(() => {
        const chart =
            chartRef.current && echarts.getInstanceByDom(chartRef.current);
        if (chart) {
            chart.resize();
        }
    }, [chartRef, size]);
};
export default useEchartResizer;

 // useComponentSize.ts

import React, { useState, useLayoutEffect } from "react";

function getSize(el) {
    if (!el) {
        return {};
    }
    return {
        width: el.offsetWidth,
        height: el.offsetHeight,
    };
    // 之前求高度都是用的getComputedClientRect()这个方法
}

export default function useComponentSize(ref) {
    let [size, setSize] = useState(getSize(ref.current));

    function handleResize() {
        if (ref && ref.current) {
            setSize(getSize(ref.current));
        }
    }
    useLayoutEffect(() => {
        handleResize();
        // 第一次初始化就执行一遍
        let resizeObserver = new ResizeObserver(() => handleResize());
        // 定义一个检测变动的状态机
        resizeObserver.observe(ref.current);
        // 把这个检测机制绑定到当前元素
        return () => {
            resizeObserver.disconnect(ref.current);
            resizeObserver = null;
        };
    }, []);

    return size;
}