Nivo ResponsiveBar 页面F5刷新时柱条宽度塌陷问题
Nivo ResponsiveBar 刷新后柱条宽度塌陷修复
触发原因
ResponsiveBar 初始化时如果外层容器尺寸计算时机早于DOM实际挂载完成,会拿到错误的容器宽度值,最终折算出来的柱条宽度会接近0。和ResponsiveLine的实现逻辑不同,Bar组件的柱宽计算仅在初始化、容器监听到resize事件时触发重算。F5刷新时如果图表容器随父组件异步渲染(路由懒加载、数据请求完成后才渲染容器、CSS动画控制容器显隐等场景),就会命中这个时机差问题,手动触发window resize后柱宽恢复是该问题的典型特征。
修复方案(按优先级排序)
- 延迟挂载图表组件,等容器DOM尺寸稳定后再渲染ResponsiveBar
页面初始化阶段不直接渲染图表,等容器布局稳定后再挂载,不会丢失任何内置功能。参考实现:const [chartReady, setChartReady] = useState(false) useEffect(() => { // 100ms延迟足够覆盖绝大多数DOM渲染完成的时机 const renderTimer = setTimeout(() => setChartReady(true), 100) return () => clearTimeout(renderTimer) }, []) return ( <div className="bar-chart-wrapper" style={{ width: '100%', height: 400 }}> {chartReady && <ResponsiveBar {/* 原有业务配置 */} />} </div> ) - 组件挂载后主动触发resize事件,强制组件重算尺寸
如果不想加渲染判断逻辑,可以在图表组件挂载完成后手动派发一次原生resize事件,触发Nivo内置的尺寸重算逻辑,代码侵入性更低:useEffect(() => { window.dispatchEvent(new Event('resize')) }, []) - 校正外层容器CSS配置
不要给ResponsiveBar的外层父容器设置display: none初始状态,父级如果用flex布局需要给图表容器加flex: 1或明确宽度值,固定给图表容器设置width: 100%和明确高度,避免初始化时拿到错误的容器clientWidth值。
避坑提示
自定义barComponent硬编码柱宽的临时方案除了丢失原生tooltip,还会在不同屏幕尺寸下出现柱条溢出、重叠问题,不建议长期使用。上述三个修复方案均为无侵入实现,不会破坏Nivo的内置交互能力。
相同场景下ResponsiveLine无异常,是因为Line组件的尺寸监听逻辑加了初始化轮询校正,Bar组件当前版本未做这层兜底,属于组件实现差异,不是业务配置错误。
内容的提问来源于stack exchange,提问作者ethrbunny
相关产品推荐
相关产品推荐

