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

react-chartjs-2与Chart.js实现的图表修改数值时出现两次刷新问题

问题原因与解决方案

异常原因

  • 状态更新时机导致两次渲染:当country prop发生变化时,React会先触发一次组件重渲染,此时使用的还是上一次country对应的旧dailyData,图表会先基于旧数据更新一次图形;之后useEffect才会执行拉取新国家对应的数据,setDailyData触发第二次重渲染,此时才会更新x/y轴的标签数值,视觉上就表现为两次刷新。
  • 内联data对象引用不稳定:代码中每次渲染都会给Line组件传入新生成的data对象,哪怕数据内容没有变化,新的引用也会触发react-chartjs-2内部的重绘逻辑,放大了两次更新的视觉差异。
  • 初始状态设置不合理:初始dailyData为空数组,首次渲染时解构的infected、day都是undefined,也会出现一次空渲染,之后数据返回再渲染一次的情况。

可行解决方案

可以通过以下几个措施组合解决问题:

  1. 新增加载状态,请求过程中展示占位内容,不要使用旧数据渲染图表,避免出现先更新旧图形的问题。
  2. 使用useMemo缓存图表的data配置,只有当实际关联数据变化时才重新生成data对象,减少不必要的重绘。
  3. 给Line组件绑定与country关联的key属性,切换国家时直接让图表组件重新挂载,直接用新数据渲染,跳过旧数据更新的步骤。

优化后代码示例

import { useMemo, useState, useEffect } from 'react';
import { Line } from 'react-chartjs-2';

const Chart = ({country}) => {
    const [dailyData,setDailyData] = useState(null);
    const [loading, setLoading] = useState(false);

    useEffect(() => {
        const fetchAPI = async () => {
            setLoading(true);
            const res = await fetchDailyData(country);
            setDailyData(res);
            setLoading(false);
        }
        fetchAPI();
    },[country]);

    const chartData = useMemo(() => {
        if (!dailyData) return null;
        const { day, infected } = dailyData;
        return {
            labels: day.map(item => item),
            datasets: [
                {
                    data: infected.map(item => item),
                    label: 'Infected',
                    borderColor: '#3333ff',
                    fill: true,
                }
            ]
        }
    }, [dailyData]);

    if (loading) return <div>数据加载中</div>;
    if (!chartData) return null;

    return <Line key={country} data={chartData} />;
}

可选优化

如果不需要图表的入场动画,可以在Line组件的options中关闭动画,进一步避免视觉上的闪烁:

<Line 
  key={country} 
  data={chartData} 
  options={{ animation: false }} 
/>

内容的提问来源于stack exchange,提问作者guddu gupta

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.22 02:57:03