【问题标题】:How to run useEffect only once when multiple dependencies change at a same time如何在多个依赖项同时更改时仅运行一次 useEffect
【发布时间】:2023-02-26 17:27:50
【问题描述】:

我正在使用具有两个依赖项的 useEffect 挂钩,如下所示:

useEffect(() => { ..... }, [apiData, currentMeasurements]);

注意,apiData是通过apollo/client的useLazyQuery获取的。

现在在保存(例如,保存或提交表单)时,两个依赖项会同时更改,即获取 apiData 并且还使用 setState(即 setCurrentMeasurements([]))将 currentMeasurements 设置为新数组。

由于 API 调用需要时间,React 在设置 currentMeasurements 时执行一次 useEffect,并在我收到 API 响应时再执行一次。

但这不是预期的行为。这导致在渲染 useEffect 时第一次在屏幕上渲染旧值(由于 currentMeasurements 的变化),几秒钟后,渲染新数据(当 useEffect 再次运行时,因为我们获得了 newApiData)。

如何让 useEffect 仅在我收到 API 响应时运行?或者换句话说,如何让 useEffect 仅在我准备好要在 useEffect 中传递的两个依赖项时运行。

我试过但没有用的东西: 使用 setTimeOut(自定义时间)更新 currentMeasurements,但这会在 API 响应延迟时导致问题。

【问题讨论】:

    标签: javascript reactjs typescript react-hooks


    【解决方案1】:

    您可以将两个依赖项都保存为 refs,然后检查它们是否都已更改。如果没有什么也不做。如果是这样,请更新参考。

    const changedRef = useRef({});
    
    useEffect(() => { 
      if(changedRef.current.currentMeasurements !== currentMeasurements &&
         changedRef.current.apiData !== apiData) {
        
        ... // do something
        
        changedRef.current = {
          apiData
          currentMeasurements
        };
      }
    }, [apiData, currentMeasurements]);
    

    但是,使用中断条件更容易——即如果currentMeasurements 的长度为 0,则不要在useEffect 内做任何事情:

    useEffect(() => { 
      if(currentMeasurements.length === 0) return;
      
      ... // do something
    
    }, [apiData, currentMeasurements]);
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-11-22
      • 1970-01-01
      • 2011-01-08
      • 2020-05-21
      • 1970-01-01
      • 2020-01-23
      • 2021-03-03
      相关资源
      最近更新 更多