//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; }