react-google-charts报错求助:Table has no columns及无数据绘制问题
解决react-google-charts PieChart报错“Table has no columns”/“Cannot draw chart: no data specified”
核心问题分析
报错的直接原因是传给PieChart的data不符合要求:
- Google Charts的PieChart要求数据是带表头的二维数组(比如
[['分类名称', '占比'], ['A', 20], ['B', 80]]),你当前的代码只生成了数据行,没有表头。 - 状态更新逻辑混乱,导致数据没有正确被收集到状态中。
- 未处理数据加载阶段的空数据情况。
具体修复步骤
1. 修正数据格式,添加表头
PieChart必须要有表头行,否则会报“Table has no columns”。在生成数据时,先添加表头行定义列名。
2. 修复状态更新逻辑
不要在循环中多次调用setState,也不要用外层var声明数组(每次useEffect触发都会重置),而是在每次处理数据时创建新数组,一次性更新状态,符合React状态不可变的原则。
3. 处理数据加载状态
利用useQuery返回的isLoading状态,在数据加载完成前不渲染Chart,避免空数据触发报错,同时给用户明确的加载提示。
4. 清理无效依赖
移除useEffect依赖列表中未定义的chartsQueryTopographyData和chartsQueryAgeData,避免不必要的重渲染和React依赖警告。
修复后的完整代码
import { Button, Card, Col, Row, Space, Spin } from 'antd'; // 引入Spin用于加载状态提示 import { FunctionComponent, useContext, useEffect, useState } from 'react'; import ReactChart from '../../common/chart'; import { typeChart } from '../../common/chart/bar-chart/data/enum'; import '../../../styles/dashboard/index.scss'; import { AuthContext, IAuthContext } from '../../../contexts/auth-context'; import colors from '../../../constants/colors'; import calendar1 from '../../../assets/icons/calendar1-icon.svg'; import calendar2 from '../../../assets/icons/calendar2-icon.svg'; import calendar3 from '../../../assets/icons/calendar3-icon.svg'; import thermometer from '../../../assets/icons/thermometer-icon.svg'; import waving from '../../../assets/icons/waving-hand-icon.svg'; import { useNavigate } from 'react-router'; import { FormattedMessage } from 'react-intl'; import { useQuery } from 'react-query'; import statisticCharts from '../../../api/nuclearMedicineApi/services/Statistic'; import { BsFillSquareFill } from 'react-icons/bs'; import { Chart } from "react-google-charts"; interface DashboardProps { } const Dashboard: FunctionComponent<DashboardProps> = () => { const auth = useContext<IAuthContext>(AuthContext); const navigate = useNavigate(); // 获取数据并解构出加载状态 const { data: chartsQueryCityData, isLoading } = useQuery(['chartsQueryCityData'], () => statisticCharts.GetTopographyStatistic({ FilterType: 2 }), ); const [xyCitytotalTopography, setxyCitytotalTopography] = useState<any[]>([]) useEffect(() => { if (!chartsQueryCityData?.resultList) return; // 数据未返回时直接退出 // 创建新数组,先添加表头行 const newCityTopography = [['城市', '占比']]; // 遍历过滤有效数据 chartsQueryCityData.resultList.forEach((xy: any) => { if (xy?.x !== undefined && xy?.yPercent !== undefined && xy?.yPercent !== 0) { newCityTopography.push([xy.x, xy.yPercent]); } }); // 一次性更新状态 setxyCitytotalTopography(newCityTopography); }, [chartsQueryCityData]); // 仅保留有效依赖 const options = { is3D: true, }; const current = new Date(); const date = `${current.getFullYear()}/${current.getMonth() + 1}/${current.getDate()}`; return ( <> <div className='dashdoard-donutData'> <Row> <Col className='mt-8'> {/* 根据状态渲染对应内容 */} {isLoading ? ( <Spin size="large" /> ) : xyCitytotalTopography.length > 1 ? ( // 确保有表头+至少一条数据才渲染图表 <Chart chartType="PieChart" data={xyCitytotalTopography} options={options} width="100%" height="400px" /> ) : ( <div>暂无有效统计数据</div> // 无数据时显示友好提示 )} </Col> </Row> </div> </> ); }; export default Dashboard;
额外说明
- 使用
forEach替代map:遍历处理数据无需返回值,forEach语义更清晰。 - 严格数据校验:过滤掉空值和占比为0的数据,避免无效数据干扰图表渲染。
- 空状态处理:无有效数据时显示提示文本,提升用户体验。
内容的提问来源于stack exchange,提问作者Hiba Youssef
相关产品推荐
相关产品推荐

