【问题标题】:Is React Strict mode causing my component to call my API more times than usual?React Strict 模式是否会导致我的组件调用我的 API 的次数比平时多?
【发布时间】:2021-08-14 04:10:42
【问题描述】:

我是 React 的初学者,我尝试每 3 秒调用一次此 API,以获取国际空间站坐标并将它们呈现到每次调用的屏幕上。所以我使用 setTimeout() 获取 API 坐标,更新 'coords' 状态变量,然后使用 useEffect 将 ref 'coordRef' 更新为这些值,然后我将其传递给子组件 'TomTomSearch',以用作嗯。

问题是,当我在严格模式下运行它时,它会进行许多 API 调用,然后最终会产生一个永无止境的 API 调用流,正如运行时的多个控制台日志所看到的那样,当我在没有严格模式的情况下运行它时模式标签,它只调用一次 setTimeout() 调用。我使用的 API 限制为 1 次调用/秒,并且最终在严格模式下总是给我一个 429 错误。

145 FetchISS.js:21 fetched //(console logged 145 times in 15 seconds)
FetchISS.js:17 
GET https://api.wheretheiss.at/v1/satellites/25544 
429 (Too Many Requests)

我只需要知道这是否只是使用严格模式的副作用,还是我实际上只是以错误的方式执行此操作。此外,对于您看到的任何丑陋代码的任何指针或建议将不胜感激!

function FetchISS() {
  const [ coords, setCoords] = useState({lat: null, lon: null});
  const coordRef = useRef({lat: null, lon: null});

  useEffect(
    () => {
      coordRef.current = {lat: coords.lat, lon: coords.lon};
    }
  ,[coords]);

  function fetchISS() {
    const iss_API = 'https://api.wheretheiss.at/v1/satellites/25544';
    fetch(iss_API)
    .then(results => results.json())
    .then(results => {
      setCoords({lat: results.latitude, lon: results.longitude});
      console.log('fetched');
    }).catch(err => {
      console.log(err.message);
    })
  }

  setTimeout(() => fetchISS(), 3000);

  return(
    <div>
      { coordRef.current.lat !== null && coordRef.current.lon !== null ? 
      <TomTomSearch coords={coords} /> : null } 
    </div>
  )
}

【问题讨论】:

    标签: reactjs api react-hooks infinite-loop


    【解决方案1】:

    您正在组件中创建一个无限循环的获取。当 API 响应时,您的组件会重新呈现,并且由于您的 setTimeout 调用不在 useEffect 调用内,因此每次呈现组件时都会运行它,从而创建一个循环。

    请参阅this question,了解如何在 react 中每隔几秒调用一次函数。

    【讨论】:

    • 您是说 fetch 调用本身会导致重新渲染?或者我在 fetch 调用中设置我的状态会导致重新渲染?我尝试将 setTimeout() 函数放在 useEffect 调用中,但我得到相同的结果,一个无限循环。如果我将 setTimeout 放在 useEffect 调用中,组件会在重新渲染之前等待它完成吗?
    • 我想我明白了:我将 API 调用逻辑放入了 fetchISS() 函数中。然后我在我的组件中调用 useEffect() 两次。第一次调用是一个空的依赖数组,所以它只被调用一次。第二个 useEffect 调用依赖于一个名为“effectCall”的状态对象,我专门为调用它而创建了它。在两个 useEffect 调用中,我更改了 'effectCall' 的值,以便它重新渲染组件。我用它来改变'effectCall'的状态:
    • const [ effectCall, setEffectCall ] = useState(false); setEffectCall(prev => !prev);
    • 忘了提一下:在第二个 useEffect(具有依赖项的那个)中,我在 3 秒 setInterval() 上调用了 fetchISS()。我希望这可以帮助其他遇到此问题的人,我希望这是一个适当的解决方案。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多