javascript - 自定义 useFetch Hook 中的无限循环

标签 javascript reactjs react-hooks render

所以我不确定到底是什么导致了这个问题或如何正确解决这个问题。

我有一个自定义的 useFetch Hook 来获取数据。它唯一特别的地方是你可以提供一个函数来修改获取的结果。 useFetch 钩子(Hook)是由某个我无法再联系到的人编写的。

这是一个完整的、独立的codesandbox示例来重现这一点:

https://codesandbox.io/s/optimistic-lalande-glhg3?file=/src/App.js:192-326

您可以看到所选行 (192-326) 已被注释掉。它是组件上方对象的副本。

当在组件内部的 init-object 中进行注释时,useFetch 钩子(Hook)开始无限地获取 url。

这可能与变量或值的更改/重新渲染有关,但我不明白。

最佳答案

每次渲染都会使用新引用创建新对象init,但内容是相同的。然后这个效果跟踪这个引用并执行状态更新。那么状态更新会导致重新渲染,从而导致新的初始化对象触发效果...

 useEffect(() => {
    setLoading();
    [...successModifiers, (result) => setResource(result)].reduce(
      (previous, current) => previous.then(current).catch(setError),
      fetch(url, init).catch((error) => setError(error))
    );
  }, [url, init, successModifiers]);
//         ^^^^^

要解决这个问题,您可以使用 useMemo 持久化对象引用:

const init = useMemo(() => ({/*...*/}));

但这可能会使 useFetch 的使用有点笨拙,因此替代方案是基于深度比较将对象持久保存在 useFetch 中。像这样的事情:


function useDeepMemo(object) {
  const ref = useRef(object);

  if (!deepEquals(object, ref.current)) {
    ref.current = object;
  }

  return ref.current;
}

关于javascript - 自定义 useFetch Hook 中的无限循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/63806887/

相关文章:

javascript - 如何确保唯一的电子邮件、用户名将使用 Mongoose 输入到 MongoDB

reactjs - 包含 useContext 钩子(Hook)会导致子级的 useState 重置为初始值

javascript - 我们可以在reactjs hooks中使用useState()的对象解构吗?

reactjs - 使用 useState 和 useContext React Hooks 持久化 localStorage

javascript - 如何处理两个日期之间验证的错误?

javascript - AngularJS HTML 中未应用 CSS 样式

java - 如何在 Play Framework 中重新创建 nginx 的 try_files 以托管 React 站点

reactjs - 如果你在做样式组件,你如何在 React 中重置 CSS?

javascript - 循环时await 调用会并行执行吗?

javascript - 如果子元素存在于带有 React 的大型菜单的循环中,则应用类