React中Chart.js图表初始加载时数据不显示问题求助
解决React中Chart.js首次加载无数据的问题
问题根源
- 组件挂载时,负责渲染图表的
useEffect依赖为空数组,仅执行一次,此时后端请求还未完成,backendData还是初始的[{}],导致图表使用无效数据渲染。 nethkinData定义在组件顶层,不会随着backendData的更新自动重新计算,且渲染图表的useEffect未监听数据变化,因此后端数据返回后不会触发图表更新。
修复步骤
- 修正初始状态:将
backendData的初始值从[{}]改为[],避免空对象导致的undefined数据。 - 缓存图表数据:用
useMemo包裹nethkinData,依赖backendData,确保数据变化时自动更新图表数据源。 - 监听数据变化更新图表:给渲染图表的
useEffect添加backendData依赖,当数据返回后自动销毁旧图表并创建新图表。 - 添加加载状态(可选):在数据未加载完成时显示加载提示,提升用户体验。
修改后的代码
import { useState, useEffect, useMemo } from 'react'; import Axios from 'axios'; import Chart from 'chart.js/auto'; import Head from 'next/head'; import Sidebar from './Sidebar'; import styles from './your-styles.module.css'; // 替换为你的样式文件路径 function Bar() { const [backendData, setBackendData] = useState([]); const [isLoading, setIsLoading] = useState(true); // 发起后端数据请求 useEffect(() => { Axios.get('http://localhost:3001/get') .then((response) => { setBackendData(response.data); setIsLoading(false); }) .catch((err) => { console.error('数据请求失败:', err); setIsLoading(false); }); }, []); // 缓存图表数据,仅在backendData变化时重新计算 const nethkinData = useMemo(() => ({ labels: backendData.map(item => item.time), datasets: [{ data: backendData.map(item => 30 - item.total), label: "Empty parking spaces", fill: true, backgroundColor: "rgba(211,211,211,0.5)", borderColor: "rgb(211,211,211)" }] }), [backendData]); // 图表配置选项 const nethkinOptions = { scales: { y: { suggestedMin: 0, suggestedMax: 30, ticks: { color: 'Grey' }, grid: { display: true } }, x: { ticks: { color: 'Grey' } } }, animation: { y: { duration: 3000, from: 3000 } } }; // 监听数据变化,更新图表 useEffect(() => { if (isLoading || backendData.length === 0) return; const ctx = document.getElementById('nethkinChart').getContext('2d'); const existingChart = Chart.getChart("nethkinChart"); // 销毁旧图表避免冲突 if (existingChart) existingChart.destroy(); // 创建新图表 new Chart(ctx, { type: 'line', data: nethkinData, options: nethkinOptions }); // 组件卸载时清理图表,防止内存泄漏 return () => { const chart = Chart.getChart("nethkinChart"); if (chart) chart.destroy(); }; }, [backendData, nethkinData, isLoading]); return ( <> <Head> <link rel="icon" href="/latech.ico"/> <title>Parking Statistics</title> </Head> <Sidebar pageWrapId={'page-wrap'} outerContainerId={'outer-container'}/> <div className={styles.navbar}> <h2>Parking Statistics</h2> </div> <div className={styles.chart}> <h2>Nethkin Stats</h2> {isLoading ? ( <p>加载中...</p> ) : ( <canvas id='nethkinChart'></canvas> )} </div> </> ); } export default Bar;
关键说明
useMemo确保图表数据仅在后端数据变化时重新生成,避免不必要的性能消耗。- 渲染图表的
useEffect依赖backendData,保证数据返回后自动触发图表更新。 - 组件卸载时销毁图表,防止内存泄漏问题。
内容的提问来源于stack exchange,提问作者hedgers
相关产品推荐
相关产品推荐

