React页面加载时axios发起GET请求后渲染am4charts无数据如何解决
问题根因
- 初始执行时,
useEffect空依赖仅执行一次,此时异步GET请求尚未返回,feedback为空值,生成的dataArray是空数组,图表初始化时绑定的是空数据。 - 异步请求返回后调用
setFeedback触发组件重渲染,但图表初始化逻辑不会重新执行,也没有监听数据变化更新图表配置,因此图表一直保持无数据状态。 - 热重载生效的原因是热重载会保留当前已加载的
feedback状态,再重新执行组件初始化逻辑,此时dataArray已有数据,图表就能正常渲染。 - 之前尝试的修复方案错误原因:将
getFeedback放入依赖为feedback的useEffect中,会导致setFeedback触发feedback更新,再调用getFeedback,形成无限请求循环;双空依赖的方案未做数据更新后的图表同步,因此还是无数据。
可行解决方案
修改逻辑如下:
- 拆分逻辑:空依赖的
useEffect仅负责图表初始化,不绑定数据 - 单独空依赖的
useEffect负责页面加载时拉取一次数据,避免循环请求 - 新增依赖为
feedback的useEffect,仅负责数据更新后同步到图表实例,am4charts会自动触发重绘 - 初始
feedback状态修改为空数组,符合数据类型语义
修改后的完整代码:
import * as am4core from "@amcharts/amcharts4/core"; import * as am4charts from "@amcharts/amcharts4/charts"; import React, { useRef, useState, useEffect } from 'react'; import axios from "axios"; function UnderstandingGraph(props) { // 初始状态改为空数组,符合数据类型 const [feedback, setFeedback] = useState([]); const chart = useRef(null); // 仅执行一次:初始化图表,不绑定数据 useEffect(() => { let x = am4core.create("chartdiv", am4charts.XYChart); x.paddingRight = 20; x.dateFormatter.dateFormat = "yyyy-MM-dd"; let dateAxis = x.xAxes.push(new am4charts.DateAxis()); dateAxis.renderer.grid.template.location = 0; let valueAxis = x.yAxes.push(new am4charts.ValueAxis()); valueAxis.tooltip.disabled = true; valueAxis.renderer.minWidth = 35; let series = x.series.push(new am4charts.LineSeries()); series.dataFields.dateX = "date"; series.dataFields.valueY = "understanding"; series.tooltipText = "{valueY.value}"; x.cursor = new am4charts.XYCursor(); let scrollbarX = new am4charts.XYChartScrollbar(); scrollbarX.series.push(series); x.scrollbarX = scrollbarX; chart.current = x; return () => { x.dispose(); }; }, []); // 仅执行一次:页面加载时拉取数据 useEffect(() => { getFeedback(); }, []); // 监听feedback变化,同步数据到图表 useEffect(() => { if (!chart.current) return; const dataArray = feedback.map(item => ({ date: item.date, understanding: item.understanding })); // 直接更新图表的data属性,am4charts自动重绘 chart.current.data = dataArray; }, [feedback]); const getFeedback = () => { axios.get('/feedback') .then( (response) => { setFeedback(response.data) }) .catch((error) => { console.log(`服务端错误`, error); }); } return( <div id="chartdiv" style={{ width: "100%", height: "500px" }}></div> ); }; export default UnderstandingGraph;
内容的提问来源于stack exchange,提问作者MMettille
相关产品推荐
相关产品推荐

