【问题标题】:Chart refreshing twice图表刷新两次
【发布时间】:2021-05-10 15:52:54
【问题描述】:

使用 react-chartjs-2 和 chartjs 创建的图表在更改值时刷新 2 次。第一次,只有图形的形状发生变化,第二次,y 轴和 x 轴上的值发生变化。

const Chart = ({country}) => {
    const [dailyData,setDailyData] = useState([]);
    useEffect(() => {
        const fetchAPI = async () => {
            setDailyData(await fetchDailyData(country))
        }
        fetchAPI();
    },[country]);
   const {day,infected,recoveries,deaths} = dailyData;
    const lineChart = (
        infected? (<Line
        data={{
            labels: day.map((data ) => (data)),
            datasets:[
                {
                    data:  infected.map((data) => (data)),
                    label: 'Infected',
                    borderColor: '#3333ff',
                    fill: true,
                }],
        }}
        /> ) : null

      
    )

【问题讨论】:

  • 为什么将 fetchAPI 定义放在 useEffect 中?
  • 您可能想尝试将 useEffect 更改为 useLayoutEffect 以防止 React 异步绘制。
  • @AnoopJoshi 将 fetchAPI 放入 useEffect 是一种防止因未将“fetchAPI”放入 useEffect 依赖项而对您大喊大叫的反应。其中,如果您实际上将 fetchAPI 带到外部并将其添加为 useEffect 依赖项,那么您将获得一个无限循环。您必须使用 useCallback 钩子等修复包装 fetchAPI,无论如何,它的做法还不错。
  • @BaltasarSolanilla 我尝试使用 useLayoutEffect,但仍然面临同样的问题。
  • 抱歉,对此我无能为力。我建议您使用最小的可重现示例创建一个沙箱,它不是太多代码,应该很容易。也许其他人可以发现问题。

标签: reactjs charts


【解决方案1】:

您的dailyData 状态存在问题。 您将默认值设置为空数组,但稍后您尝试将其解构为对象。

const asd=[1,2,4,5];

const {a,b,c}=asd;

console.log (a,b,c); // undefined, undefined, undefined

const [e,f,g]=asd; 

console.log (e,f,g); // 1,2,4

但是,您说您的图表在第二次闪烁后仍然有效。这意味着您的原始空数组不是 useState 挂钩的正确默认值。应该使用null 并在解构之前检查它。

更新: 如果数据也被加载两次,图表可能会闪烁两次。 useEffect 应该有一个 if 语句来检查数据是否已经加载并且仅在没有加载时才加载。可能您可以添加另一个加载状态。所以你不会有两个并发的 API 调用。

您的代码如下所示:

const Chart = ({country}) => {
    const [dailyData,setDailyData] = useState(null);
    useEffect(() => {
        if(country && !dailyData){
          const fetchAPI = async () => {
            
            setDailyData(await fetchDailyData(country))
          }
          fetchAPI();
        }
    },[country]);
    let lineChart=null
    if (dailyData){
        const {day,infected,recoveries,deaths} = dailyData;
        lineChart = (<Line
            data={{
                labels: day.map((data ) => (data)),
                datasets:[
                    {
                        data:  infected.map((data) => (data)),
                        label: 'Infected',
                        borderColor: '#3333ff',
                        fill: true,
                    }],
            }}
        /> )
    }
}

【讨论】:

  • 感谢回答,不过还是刷新了两次。
  • 但现在它显示的是第一个选定国家的数据。可能由于 !dailyData 条件而无法获取其他国家/地区的数据。
  • 您可以检查当前加载的数据是否适用于当前国家。如果不是,则为当前国家/地区加载它。这应该与 !dailyData 的状态相同。
猜你喜欢
  • 1970-01-01
  • 2016-04-15
  • 2013-04-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-01
相关资源
最近更新 更多