react-chartjs2点击图表最后一个柱状图时触发崩溃报错求助
React-ChartJS2 柱状图钻取点击最后一个柱子时崩溃问题
我用react-chartjs2 + ChartJS开发公司仪表盘,其中一个组件做了柱状图钻取功能:点击一级柱状图的柱子加载二级图表,点击二级图表的柱子加载三级表格。但点击一级图表的最后一个柱子(对应最后一个index和datasetIndex)时,应用直接崩溃,报错指向二级图表的数据加载环节,且仅在该场景下触发。
核心代码实现
currentLevel是React状态,用于控制当前钻取层级:
const handleFirstLevelClick = async (event, chartElement) => { try { await firstLevel(chartElement); let selectedApplication = getFirstLevelDatasets()[chartElement[0].datasetIndex].label; let selectedMonth = getFirstLevelLabels()[chartElement[0].index]; if (widget[1].arrayList.filter((item) => item.job_number.includes(selectedApplication.substring(selectedApplication.lastIndexOf("#")+1)) && item.month === selectedMonth).length >0) { setCurrentLevel(2); } else { setCurrentLevel(1); } } catch (error) { console.log(error); } } const handleSecondLevelClick = async (event, chartElement) => { try { await secondLevel(chartElement); let selectedJob = getSecondLevelLabels()[chartElement[0].index]; if (widget[2].arrayList.filter((item) => item.job_number.includes(selectedJob.substring(selectedJob.lastIndexOf("#")+1))).length >0) { setCurrentLevel(3); } else { setCurrentLevel(2); } } catch (error) { console.log(error); } } const firstLevel = async (chartElement) => { const { datasetIndex } = chartElement[0]; let selectedApplication = getFirstLevelDatasets()[datasetIndex].label; let selectedMonth = getFirstLevelLabels()[chartElement[0].index]; setSelectedApplication(selectedApplication); setSelectedMonth(selectedMonth); } const secondLevel = async (chartElement) => { const { index } = chartElement[0]; let selectedJob = getSecondLevelLabels()[index]; setSelectedJob(selectedJob); } const renderComponent = () => { switch (currentLevel) { case 1: return <Bar data={dataFirstLevel} options={firstLevelChartOptions} /> case 2: return <Bar data={dataSecondLevel} options={secondLevelChartOptions} /> case 3: return <MailingStatusTable data={dataThirdLevel} /> } } dataSecondLevel = { labels: getSecondLevelLabels(), datasets: [ { label: 'Delivered Percent', data: getSecondLevelDeliveredPercent(), backgroundColor: 'rgba(0, 255, 0, 0.2)', borderColor: 'rgba(0, 255, 0, 1)', borderWidth: 1, }, // 其他数据集结构类似 ] } const secondLevelChartOptions = { onClick: handleSecondLevelClick, // 其他图表配置项 }
图表渲染时会立即调用数据获取函数,点击事件触发后更新currentLevel状态,触发组件重新渲染加载对应层级内容。
排查与解决建议
给数据函数加边界兜底
点击最后一个一级柱子时,selectedApplication或selectedMonth可能导致getSecondLevelLabels()/getSecondLevelDeliveredPercent()返回空数组或undefined,ChartJS渲染空数据会报错。给这些函数加兜底:const getSecondLevelLabels = () => { const rawLabels = /* 原逻辑 */; return rawLabels.length > 0 ? rawLabels : ['暂无数据']; }点击事件加索引合法性校验
在handleFirstLevelClick里先判断索引是否在有效范围内,避免越界访问:const handleFirstLevelClick = async (event, chartElement) => { try { if (!chartElement || chartElement.length === 0) return; const { datasetIndex, index } = chartElement[0]; const datasets = getFirstLevelDatasets(); const labels = getFirstLevelLabels(); // 校验索引是否超出数组长度 if (datasetIndex >= datasets.length || index >= labels.length) return; firstLevel(chartElement); // 去掉await,setState不返回Promise let selectedApplication = datasets[datasetIndex].label; let selectedMonth = labels[index]; // 后续逻辑... } catch (error) { console.error('一级图表点击出错:', error); } }二级图表渲染前做空数据判断
在渲染二级图表前先检查数据有效性,避免渲染空图表:case 2: if (!dataSecondLevel?.labels || dataSecondLevel.labels.length === 0) { return <div>暂无二级数据</div>; } return <Bar data={dataSecondLevel} options={secondLevelChartOptions} />
有人遇到过类似问题吗?
内容的提问来源于stack exchange,提问作者Vinicius Bretzke Müller
相关产品推荐
相关产品推荐

