react+echarts出现“There is a chart instance already initialized on the dom.”

发布时间 2023-03-22 21:11:48作者: 流云君

写了一个关于echatrs组件,报错dom重复

配置信息从props拿
  let chart;
  useEffect(() => {
      if (chart) {
        updateChartView();
      }else{
	  chart = echarts.init(dom.current)
	   updateChartView();
	   handleWindowResize();
	  }
    }
  }, [configOption]);
  
   useEffect(() => {
    return () => {
      if (chart) {
        chart.dispose(dom.current);
        chart.clear();
        window.resize = null;
      }
      window.removeEventListener("resize", handleWindowResize);
    };
  }, []);

react更新不能及时取定义数据,最好用usestate创建实例

修改后
   const [chart, setChart] = useState(null)
  const { configOption } = props;
  useEffect(() => {
    if (JSON.stringify(configOption) !== "{}") {  
      if (chart) {
        // chart.setOption(configOption, true);
        updateChartView();
      }
    }
  }, [configOption]);
  useEffect(() => {
    let echartsInit = echarts.init(dom.current);
    setChart(echartsInit);
    updateChartView();
    handleWindowResize();
    return () => {
      if (chart) {
        chart.dispose(dom.current);
        chart.clear();
        window.resize = null;
      }
      window.removeEventListener("resize", handleWindowResize);
    };
  }, []);

组件完整代码--简单版

import React, { useEffect, useState, memo, createRef } from "react";
import { merge, debounce } from "lodash"; // 按需引入
import * as echarts from "echarts";
function Fn(props) {
  const dom = createRef();
  const [chart, setChart] = useState(null)
  const { configOption } = props;
  useEffect(() => {
    if (JSON.stringify(configOption) !== "{}") {  
      if (chart) {
        // chart.setOption(configOption, true);
        updateChartView();
      }
    }
  }, [configOption]);
  useEffect(() => {
    let echartsInit = echarts.init(dom.current);
    setChart(echartsInit);
    updateChartView();
    handleWindowResize();
    return () => {
      if (chart) {
        chart.dispose(dom.current);
        chart.clear();
        window.resize = null;
      }
      window.removeEventListener("resize", handleWindowResize);
    };
  }, []);
  const basicOption = {
    // title: {
    //   textStyle: {
    //     color: "#fff",
    //   },
    // },
    grid: {
      top: 30,
      right: 10,
      left: 40,
      bottom: 10,
      containLabel: true,
    },
    tooltip: {
      trigger: "item",
    },
    legend: {
      top: "5%",
      left: "center",
    },
    series: [],
  };
  const assembleDataToOption = () => {
    if (!configOption) return;
    return merge({}, basicOption, configOption);
  };
  /**
   * 更新echart视图
   */
  const updateChartView = () => {
    if (!chart) return;
    const fullOption = assembleDataToOption();
    chart.setOption(fullOption, true);
  };

  /**
   * 当窗口缩放时,echart动态调整自身大小
   */
  const handleWindowResize = () => {
    const __resizeHandler = debounce(() => {
      if (chart) {
        chart.resize(); // 重置echarts图形绘制区域
      }
    }, 100);
    window.addEventListener("resize", __resizeHandler);
    // 监听要是一个函数所以this.__resizeHandler,不能带()
  };
  return <div ref={dom} style={{ width: "100%", height: "100%" }}></div>;
}
export default memo(Fn);