react echarts刷新不显示问题的解决方法

 更新时间:2024年02月29日 10:40:18   作者:huoyueyi  
最近在写项目的时候遇到了一个问题,当编辑完代码后echarts图正常展示 , 可再次刷新页面 , echarts会消失,所以本文给大家介绍了react echarts刷新不显示问题原因和解决方法,需要的朋友可以参考下

遇到了一个问题 , 当编辑完代码后echarts图正常展示 , 可再次刷新页面 , echarts会消失

问题如下图

要实现的效果

原因 : ECharts 初始化时找不到对应的 DOM 元素 , 在 React 中,DOM 元素是在组件渲染后才生成的,而你在初始化 ECharts 时试图访问还未渲染完成的 DOM 元素。

import React, { useEffect, useState, useRef } from 'react';
import aa from '@/assets/images/图标.png';
import bb from '@/assets/images/图标1.png';
import cc from '@/assets/images/图标2.png';
import dd from '@/assets/images/图标3.png';
import * as echarts from 'echarts';
import { salesStatistics } from './request';
 
const OrderSalesStatistics = () => {
  const sale = (data) => {
    const xAxisData = data.map((item) => item.month);
    const seriesData = data.map((item) => item.price);
 
    const saleOption = {
      title: {
        text: '销售总金额(元)/月',
        left: 'left',
      },
      tooltip: {
        trigger: 'axis',
        axisPointer: {
          type: 'shadow',
        },
      },
      grid: {
        left: '3%',
        right: '4%',
        bottom: '3%',
        containLabel: true,
      },
      xAxis: [
        {
          type: 'category',
          data: xAxisData,
          axisTick: {
            alignWithLabel: true,
          },
          axisLabel: {
            interval: 0, // 强制显示所有标签
            formatter: function (value, index) {
              // 仅显示 1、3、5、7、9、11 月的标签
              if ((index + 1) % 2 !== 0) {
                return value + '月';
              } else {
                return '';
              }
            },
          },
        },
      ],
      yAxis: [
        {
          type: 'value',
          splitLine: {
            show: false, // 取消 y 轴的横线
          },
        },
      ],
      series: [
        {
          name: 'Direct',
          type: 'bar',
          barWidth: '60%',
          data: seriesData,
          itemStyle: {
            color: '#d48ca0',
          },
        },
      ],
    };
    const saleEchart = echarts.init(document.getElementById('totalSalesAmount'));
    saleEchart.setOption(saleOption);
  };
  const teachers = (data) => {
    const seriesData = data.map((item) => ({
      name: item.teacher_name,
      value: item.price,
    }));
    const option = {
      title: {
        text: '老师业绩分布TOP10',
        left: 'left',
      },
      tooltip: {
        trigger: 'item',
      },
      legend: {
        orient: 'horizontal', // 将 orient 设置为 'horizontal'
        top: '5%', // 调整 top 属性的值,控制图例位置
      },
      series: [
        {
          name: 'Access From',
          type: 'pie',
          radius: '50%',
          data: seriesData,
          emphasis: {
            itemStyle: {
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)',
            },
          },
          labelLine: {
            show: false,
          },
          label: {
            // 添加label属性,在formatter函数中获取price和ratio
            formatter: function (params) {
              const { price, ratio } = data[params.dataIndex];
              return `${params.name} ${(ratio * 100).toFixed(2)}%`;
            },
          },
        },
      ],
    };
 
    const teacherEchart = echarts.init(document.getElementById('teacherPerformance'));
    teacherEchart.setOption(option);
  };
 
  const books = (data) => {
    const seriesData = data.map((item) => ({
      name: item.book_name,
      value: item.price,
    }));
    console.log('seriesData-book', seriesData);
 
    const option = {
      title: {
        text: '书籍业绩分布TOP10',
        left: 'left',
      },
      tooltip: {
        trigger: 'item',
        formatter: function (params) {
          return `<div style="display: flex; align-items: center;">
                          <div style="width: 10px; height: 10px; border-radius: 50%; background-color: ${params.color}; margin-right: 10px;"></div>
                          <span style="color: ${params.color}">镜像地址</span> : ${params.name}
                        </div>`;
        },
      },
      series: [
        {
          name: '库存情况',
          type: 'pie',
          radius: '68%',
          center: ['50%', '50%'],
          clockwise: false,
          data: seriesData,
          label: {
            normal: {
              textStyle: {
                color: '#999',
                fontSize: 14,
              },
            },
          },
          labelLine: {
            //取消选中饼图后往外指的小横线
            normal: {
              show: false,
            },
          },
          itemStyle: {
            //饼图之间的间距
            normal: {
              borderWidth: 4,
              borderColor: '#ffffff',
            },
            emphasis: {
              borderWidth: 0,
              shadowBlur: 10,
              shadowOffsetX: 0,
              shadowColor: 'rgba(0, 0, 0, 0.5)',
            },
          },
        },
      ],
      color: ['#00acee', '#52cdd5', '#79d9f1', '#a7e7ff', '#c8efff'],
      backgroundColor: '#fff',
    };
 
    const bookEchart = echarts.init(document.getElementById('bookPerformance'));
    bookEchart.setOption(option);
  };
 
  const [tabArr, setTabArr] = useState([]);
  const [type, setType] = useState('');
 
  // 在组件内部定义 refs , 解决一刷新就消失
  const totalSalesAmountRef = useRef(null);
  const teacherPerformanceRef = useRef(null);
  const bookPerformanceRef = useRef(null);
 
  const initAllEcharts = async () => {
    const data = await salesStatistics();
    let { salesAmount, teacher, book, order_num, buy_num, average, income } = data;
    setType(data.type);
    console.log('type', type);
    if (data.type === 2) {
      sale(salesAmount);
      books(book);
    } else if (data.type === 1) {
      sale(salesAmount);
      teachers(teacher);
    }
 
    setTabArr([
      { name: '总订单数', value: order_num },
      { name: '总购买人数', value: buy_num },
      { name: '平均客单价', value: average },
      { name: '预计总收入', value: income },
    ]);
  };
 
  useEffect(() => {
    initAllEcharts();
  }, []);
 
  useEffect(() => {
    const initCharts = async () => {
      const data = await salesStatistics();
      let { salesAmount, teacher, book, order_num, buy_num, average, income } = data;
      setType(data.type);
 
      if (data.type === 2) {
        if (totalSalesAmountRef.current && bookPerformanceRef.current) {
          sale(salesAmount, totalSalesAmountRef.current);
          books(book, bookPerformanceRef.current);
        }
      } else if (data.type === 1) {
        if (totalSalesAmountRef.current && teacherPerformanceRef.current) {
          sale(salesAmount, totalSalesAmountRef.current);
          teachers(teacher, teacherPerformanceRef.current);
        }
      }
 
      setTabArr([
        { name: '总订单数', value: order_num },
        { name: '总购买人数', value: buy_num },
        { name: '平均客单价', value: average },
        { name: '预计总收入', value: income },
      ]);
    };
 
    initCharts();
  }, []);
 
  return (
    <div className='sales'>
      <div className='items'>
        {tabArr.map((item, index) => (
          <div className='item' key={Math.random()}>
            <div className='img'>
              {index === 0 && <img src={aa} alt='' />}
              {index === 1 && <img src={bb} alt='' />}
              {index === 2 && <img src={cc} alt='' />}
              {index === 3 && <img src={dd} alt='' />}
            </div>
            <div className='cont'>
              <div className='title'>{item.name}</div>
              <div className='total'>{item.value}</div>
            </div>
          </div>
        ))}
      </div>
 
      <div className='echarts'>                       // html部分也要加上ref
        {type === 1 ? (
          <>
            <div className='echarts-item' id='totalSalesAmount' ref={totalSalesAmountRef}></div>
            <div className='echarts-item' id='teacherPerformance' ref={teacherPerformanceRef}></div>
          </>
        ) : type === 2 ? (
          <>
            <div className='echarts-item' id='totalSalesAmount' ref={totalSalesAmountRef}></div>
            <div className='echarts-item' id='bookPerformance' ref={bookPerformanceRef}></div>
          </>
        ) : null}
      </div>
    </div>
  );
};
 
export default OrderSalesStatistics;

到此这篇关于react echarts刷新不显示问题的解决方法的文章就介绍到这了,更多相关react echarts刷新不显示内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • React路由跳转的实现示例

    React路由跳转的实现示例

    在React中,可以使用多种方法进行路由跳转,本文主要介绍了React路由跳转的实现示例,具有一定的参考价值,感兴趣的可以了解一下
    2023-12-12
  • React-Hooks之useImperativeHandler使用介绍

    React-Hooks之useImperativeHandler使用介绍

    这篇文章主要为大家介绍了React-Hooks之useImperativeHandler使用介绍,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-07-07
  • React forwardRef的使用方法及注意点

    React forwardRef的使用方法及注意点

    React.forwardRef的API中ref必须指向dom元素而不是React组件,通过一段示例代码给大家介绍了React forwardRef使用方法及注意点还有一些特殊情况分析,感兴趣的朋友跟随小编一起看看吧
    2021-06-06
  • react native环境安装流程

    react native环境安装流程

    React Native 是目前流行的跨平台移动应用开发框架之一。本文介绍react native环境安装流程及遇到问题解决方法,感兴趣的朋友一起看看吧
    2021-05-05
  • react native创建项目常用插件详解

    react native创建项目常用插件详解

    文章详细介绍了React Native项目的页面路径目录设计原则、路由管理、状态管理、服务层管理、自定义hook和工具函数的使用方法、适配方案以及样式排列对齐方式,通过这些原则和方法,可以提高项目的可维护性和可扩展性
    2025-12-12
  • React前端路由应用介绍

    React前端路由应用介绍

    前端应用大多数是SPA(单页应用程序),也就是只有一个HTML页面的应用程序。因为它的用户体验更好、对服务器压力更小,所以更受欢迎。为了有效的使用单个页面来管理多页面的功能,前端路由应运而生
    2022-09-09
  • react性能优化useMemo与useCallback使用对比详解

    react性能优化useMemo与useCallback使用对比详解

    这篇文章主要为大家介绍了react性能优化useMemo与useCallback使用对比详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-08-08
  • Redux Toolkit 实战小结

    Redux Toolkit 实战小结

    Redux曾是React状态管理的标准解决方案,但传统 Redux 的样板代码过多、配置复杂、异步处理繁琐,Redux Toolkit(RTK)官方推出,旨在解决这些痛点,下面就来详细的介绍一下如何使用
    2026-03-03
  • React.memo函数中的参数示例详解

    React.memo函数中的参数示例详解

    这篇文章主要为大家介绍了React.memo函数中的参数示例详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2022-09-09
  • React项目中使用Redux的 react-redux

    React项目中使用Redux的 react-redux

    这篇文章主要介绍了React项目中使用Redux的 react-redux,文章围绕主题展开详细的内容介绍,具有一定的参考价值,需要的小伙伴可以参考一下
    2022-09-09

最新评论