React 19 通用 ECharts 组件

好,我给你做一个 React 19 通用 ECharts 组件 ,

支持饼图 / 折线图 / 柱状图,colors 可选,不传也能显示,防止重复渲染。


1. src/services/echarts.ts

注册所有需要的图表类型和组件(不用再分开写折线/饼图/柱状图)

复制代码
// src/services/echarts.ts
import * as echarts from 'echarts/core';
import {
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  ToolboxComponent
} from 'echarts/components';
import { LineChart, PieChart, BarChart } from 'echarts/charts';
import { CanvasRenderer } from 'echarts/renderers';

// 按需注册组件
echarts.use([
  TitleComponent,
  TooltipComponent,
  GridComponent,
  LegendComponent,
  ToolboxComponent,
  LineChart,
  PieChart,
  BarChart,
  CanvasRenderer
]);

export default echarts;

2. src/components/EChartsBase.tsx

一个通用的 React 19 ECharts 组件

复制代码
// src/components/EChartsBase.tsx
import React, { useRef, useEffect } from 'react';
import echarts from '@/services/echarts';

interface EChartsBaseProps {
  option: echarts.EChartsOption;
  width?: string;
  height?: string;
}

const EChartsBase: React.FC<EChartsBaseProps> = ({
  option,
  width = '100%',
  height = '400px'
}) => {
  const chartRef = useRef<HTMLDivElement | null>(null);
  const chartInstance = useRef<echarts.EChartsType | null>(null);

  useEffect(() => {
    if (chartRef.current) {
      // 如果已有实例,先销毁,防止 React 19 重复渲染
      if (chartInstance.current) {
        chartInstance.current.dispose();
      }
      chartInstance.current = echarts.init(chartRef.current);
      chartInstance.current.setOption(option);
    }

    // 监听窗口大小变化
    const handleResize = () => {
      chartInstance.current?.resize();
    };
    window.addEventListener('resize', handleResize);

    return () => {
      chartInstance.current?.dispose();
      window.removeEventListener('resize', handleResize);
    };
  }, [option]);

  return <div ref={chartRef} style={{ width, height }} />;
};

export default EChartsBase;

3. 使用示例(不传 colors 也能显示)

复制代码
// src/pages/DemoCharts.tsx
import React from 'react';
import EChartsBase from '@/components/EChartsBase';

export default function DemoCharts() {
  const pieOption = {
    title: { text: '示例饼图', left: 'center' },
    tooltip: { trigger: 'item' },
    legend: { bottom: 0 },
    series: [
      {
        name: '访问来源',
        type: 'pie',
        radius: '50%',
        data: [
          { value: 1048, name: '搜索引擎' },
          { value: 735, name: '直接访问' },
          { value: 580, name: '邮件营销' }
        ]
      }
    ]
  };

  const lineOption = {
    title: { text: '示例折线图' },
    tooltip: { trigger: 'axis' },
    xAxis: { type: 'category', data: ['Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat', 'Sun'] },
    yAxis: { type: 'value' },
    series: [
      { data: [150, 230, 224, 218, 135, 147, 260], type: 'line', smooth: true }
    ]
  };

  const barOption = {
    title: { text: '示例柱状图' },
    tooltip: {},
    xAxis: { type: 'category', data: ['苹果', '香蕉', '橘子', '梨子'] },
    yAxis: { type: 'value' },
    series: [
      { data: [5, 20, 36, 10], type: 'bar' }
    ]
  };

  return (
    <div style={{ padding: 20 }}>
      <EChartsBase option={pieOption} height="300px" />
      <EChartsBase option={lineOption} height="300px" />
      <EChartsBase option={barOption} height="300px" />
    </div>
  );
}

✅ 特点:

  • React 19 兼容

  • 饼图 / 折线图 / 柱状图通用

  • colors 可选,不传也正常显示

  • 自动销毁实例,避免 React 19 重复渲染导致的图表不显示

  • 自动响应窗口大小变化

相关推荐
Da Da 泓26 分钟前
五子棋 Web 端测试用例报告
前端·网络·websocket·网络协议·测试用例·项目
zxcvb1531 小时前
远程查看本地文档:一条轻量 Web 文件服务的工程化链路
前端·远程查看文档
niucloud-admin1 小时前
NIUCLOUD PHP SAAS上门家政使用文档:城市管理
java·前端·php
程序员大阳2 小时前
副队长JavaScript教程(50)-DOM:网页开发的起点
javascript·dom·es·节点·概念·document·关系
北岛贰2 小时前
啵啵音乐迎来全新升级!
前端
hkNaruto4 小时前
【AI】基于大模型的AI游戏地图生成、控制方案:AI Native Game Harness 迁移操作手册
前端·人工智能·游戏
IT_陈寒4 小时前
Java序列化踩坑记:对象循环引用让我加班两小时
前端·人工智能·后端
Acro4 小时前
快给macOS 上的Grok Bot换一套皮肤
前端
flash俊杰4 小时前
双引擎 OCR 编排:逐页判定、视觉优先、partial 语义与三层超时
前端
计算机魔术师4 小时前
Reddit 每周被 Google 偷走 100 万次点击,CEO 摊牌了
前端