React+TypeScript项目Highcharts mouseOver调用useState触发yAxis null报错如何解决
问题原因
你遇到的报错是状态更新触发组件重绘,导致Highcharts实例被意外销毁引发的:
你当前的图表配置options直接定义在组件内部,每次调用setPrice更新price状态时,整个组件会重新渲染,生成全新的options对象。如果没有做特殊配置,Highcharts会检测到options变化销毁原有实例、重建新图表,而此时mouseOver事件的原生逻辑还没执行完,访问已经被销毁的实例属性(yAxis)就会抛出空指针错误。
解决方案
按优先级选以下方案即可:
- 方案1:用
useMemo缓存options配置
把整个options对象用useMemo包裹,只有指定依赖项变化时才重新生成配置,避免普通状态更新导致options变更触发图表重建。参考代码:import { useMemo, useState } from 'react' const [price, setPrice] = useState<number>(0) // 缓存options,依赖项只放需要修改图表配置的变量,无相关变量就留空数组 const options = useMemo(() => ({ // 其余原有配置保持不变 plotOptions: { series: { point: { events: { mouseOver: function(e:any) { const currentPrice = // 你的价格获取逻辑 console.log(currentPrice) setPrice(currentPrice) } } } } } }), []) - 方案2:禁止Highcharts非必要更新
如果你用的是highcharts-react-official官方封装组件,给组件添加allowChartUpdate={false}属性,完全阻止配置变化引发的图表更新,适合图表配置初始化后不需要再修改的场景:<HighchartsReact highcharts={Highcharts} options={options} allowChartUpdate={false} /> - 方案3:延后状态更新时机(兜底方案)
如果前两个方案仍有问题,可以把setPrice放到setTimeout中延后执行,等Highcharts的mouseOver事件原生逻辑全部执行完成后再更新组件状态,避免逻辑冲突:mouseOver: function(e:any) { const currentPrice = // 你的价格获取逻辑 console.log(currentPrice) // 延后到下一个宏任务执行状态更新 setTimeout(() => setPrice(currentPrice), 0) }
内容的提问来源于stack exchange,提问作者ctown4life
相关产品推荐
相关产品推荐

