You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

RN Expo使用react-native-chart-kit报Invalid Number错误

react-native-chart-kit 折线图报 Invalid Number: M0, 0 L-Infinity 修复方案

问题场景

React Native Expo项目接入react-native-chart-kit做折线图时触发上述报错,点掉报错弹窗后所有功能运行正常,相关报错截图:
报错弹窗截图
控制台报错截图
实现逻辑是用useState存图表数据,初始值为空数据集,等数据库数据加载完成后再更新state传值给图表,之前用同样逻辑写其他图表没出过问题,相关代码如下:

const [lineData, setLineData] = React.useState({
  datasets: [{
    data: [],}]
})

var moodLine = []

if (value["entry"]["mood"] == 1) {
    mood1 += 1
    moodLine.push(1)
}

setLineData({
  datasets: [{
    data: moodLine,
  }]
})

<LineChart 
  data={lineData}
  width={360}
  height={220}
  bezier
  withInnerLines={false}
  fromZero={true}
  chartConfig={{
    backgroundColor: colours.white,
    backgroundGradientFrom: colours.white,
    backgroundGradientTo: colours.white,
    decimalPlaces: 0,
    color: (opacity = 1) => colours.grey,
    labelColor: (opacity = 1) => colours.black,
  }}
  style={{
    borderRadius: 16,
  }}
/>

问题根因

报错的核心原因是组件首次渲染时拿到的data是空数组。
react-native-chart-kit渲染折线时会计算X轴每个点的间距,公式是图表宽度/(数据点总数-1),空数组的时候数据点总数是0,算出来的坐标值是-Infinity,SVG路径根本不认这种非法值,直接就抛错了。
之前同样逻辑没出问题,纯粹是之前页面数据加载快,组件第一次渲染的时候已经拿到有效数据了,没撞上空数据渲染的边界情况。这次数据库数据加载慢了一拍,首屏先把空数据的图表渲染出来了,就触发了计算错误。等你点掉弹窗的时候,异步加载的数据早就回来了,state更新后组件拿有效数据重渲染,自然功能就正常了。

修复方法

  • 最稳妥的方案:加渲染拦截,数据不够的时候不渲染图表
    折线图至少要2个点才能算出正常的间距,所以判断数据集长度≥2的时候再渲染LineChart,否则直接显示加载占位,从根源上杜绝空值计算:
    {lineData.datasets[0].data.length >= 2 ? (
      <LineChart 
        data={lineData}
        width={360}
        height={220}
        bezier
        withInnerLines={false}
        fromZero={true}
        chartConfig={{
          backgroundColor: colours.white,
          backgroundGradientFrom: colours.white,
          backgroundGradientTo: colours.white,
          decimalPlaces: 0,
          color: (opacity = 1) => colours.grey,
          labelColor: (opacity = 1) => colours.black,
        }}
        style={{
          borderRadius: 16,
        }}
      />
    ) : (
      <View style={{height:220, justifyContent:'center', alignItems:'center'}}>
        <ActivityIndicator />
      </View>
    )}
    
  • 简单快速方案:改初始值,别用空数组初始化data
    给初始的data塞个默认占位值,保证第一次渲染的时候data不是空的,等真实数据回来直接替换就行:
    const [lineData, setLineData] = React.useState({
      datasets: [{
        data: [0], // 随便给个默认占位值即可
      }]
    })
    
  • 特殊场景适配:如果要展示只有1个数据点的折线图,就手动在data末尾补一个和现有值一样的冗余点,渲染的时候用hidePointsAtIndex把补的点藏起来,避免计算时间距除以0。

内容的提问来源于stack exchange,提问作者Freddie Ratsma

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.29 13:39:19