Files
gongxue-base/apps/admin/src/components/ECharts.tsx
wangziqi 1a1e90c72f fix(admin): 补全 React hooks 依赖并修复页面稳定性
- 各页面 useCallback/useMemo 依赖补全(modal/mutation/setter 等),避免闭包过期
- ECharts 使用 optionRef、MainLayout 缓存菜单转换函数、main.tsx 增加挂载点校验
- 学生同步结果改用 recordsCount 展示
2026-08-05 21:14:08 +08:00

80 lines
1.9 KiB
TypeScript

import React, { useEffect, useRef } from 'react';
import * as echarts from 'echarts/core';
import type { EChartsType } from 'echarts/core';
export type EChartsOption = Record<string, unknown>;
import {
BarChart,
CustomChart,
FunnelChart,
GaugeChart,
LineChart,
PieChart,
RadarChart,
ScatterChart,
} from 'echarts/charts';
import {
DataZoomComponent,
GridComponent,
LegendComponent,
RadarComponent,
TooltipComponent,
VisualMapComponent,
} from 'echarts/components';
import { CanvasRenderer } from 'echarts/renderers';
echarts.use([
BarChart,
CustomChart,
FunnelChart,
GaugeChart,
LineChart,
PieChart,
RadarChart,
ScatterChart,
DataZoomComponent,
GridComponent,
LegendComponent,
RadarComponent,
TooltipComponent,
VisualMapComponent,
CanvasRenderer,
]);
interface EChartsProps {
option: EChartsOption;
style?: React.CSSProperties;
className?: string;
/** 图表实例就绪回调(用于导出图片等场景) */
onReady?: (chart: EChartsType) => void;
}
const ECharts: React.FC<EChartsProps> = ({ option, style, className, onReady }) => {
const containerRef = useRef<HTMLDivElement>(null);
const optionRef = useRef(option);
optionRef.current = option;
const onReadyRef = useRef(onReady);
onReadyRef.current = onReady;
useEffect(() => {
if (!containerRef.current) return;
const chart = echarts.init(containerRef.current);
chart.setOption(optionRef.current);
onReadyRef.current?.(chart);
const observer = new ResizeObserver(() => chart.resize());
observer.observe(containerRef.current);
return () => {
observer.disconnect();
chart.dispose();
};
}, []);
useEffect(() => {
const chart = containerRef.current ? echarts.getInstanceByDom(containerRef.current) : undefined;
chart?.setOption(option, true);
}, [option]);
return <div ref={containerRef} className={className} style={style} />;
};
export default ECharts;