在项目中使用 echart 图表时,重复操作有以下几个部分可以抽出
- 获取 dom
- 初始化 echart
- 卸载销毁实例
所以编写自定义 hooks 的时候就可以考虑到以上几点
- 建一个 ref 供外部绑定,echart 初始化需要用到;
- 提供一个方法用于 echart 更新,如果调用方法时没有 echart 实例,则创建实例;
- useEffect 模拟组件卸载,此时销毁 echart 实例;
以下是完整代码
创建自定义 hooks
useEchart.ts
import { MutableRefObject, useEffect, useRef } from 'react';
import * as echarts from 'echarts';
import { getLocale } from 'umi';
interface UseEchart {
(): {
chartEl: React.RefObject<HTMLDivElement>;
echart: MutableRefObject<echarts.EChartsType | null>;
updateChart: (option: any) => void;
};
}
const useEchart: UseEchart = () => {
const chartEl = useRef<HTMLDivElement>(null);
const echart = useRef<echarts.ECharts | null>(null);
const updateChart = (option: any) => {
if (!echart.current) initChart();
echart.current?.clear();
echart.current?.setOption(option);
};
const initChart = () => {
echart.current = echarts.init(chartEl.current as HTMLDivElement, undefined, {
locale: getLocale() === 'zh-CN' ? 'ZH' : 'EN',
});
};
useEffect(() => {
// 销毁 chart 实例
return () => {
echart.current?.dispose?.();
echart.current = null;
};
}, []);
return {
chartEl,
echart,
updateChart,
};
};
export default useEchart;
组件使用
在组件中,通过 useEffect 在 props.data 发生改变时,调用 useEchart 的 updateChart 方法,传入 option 即可。
Component.tsx
import useEchart from '@/hooks/useEchart';
import { MetricScoreTrend } from '@/pages/SmartHome/data';
import moment from 'moment';
import React from 'react';
import { useEffect } from 'react';
import styles from './index.less';
type LineProps = {
data: MetricScoreTrend[];
};
const Line: React.FC<LineProps> = ({
data
}) => {
const { chartEl, updateChart } = useEchart();
useEffect(() => {
// 这里是 ecahrt option
const option = {
// xxxx
};
updateChart(option);
}, [data]);
return (
<div className={styles['line-wrap']}>
<div className={styles['line-ref']} ref={chartEl} />
</div>
);
};
export default React.memo(Line);