微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

useEffect 在更新不在依赖列表中的变量时调用导致无限循环

如何解决useEffect 在更新不在依赖列表中的变量时调用导致无限循环

我正在尝试在状态更改时执行 ajax 调用,然后将另一个状态设置为该 ajax 调用的结果。

const [plc,setPlc] = useState(null);
const [tags,setTags] = useState([]);

...

useEffect(()=>{
  if(plc != null) {
    myAjaxPromiseFunction(plc).catch((err)=>{
      console.log(err);
    }).then((tags)=>{
      setTags(tags);
    });
  }
},[plc]);

出于某种原因,这会导致无限循环。但是,当我删除 setTags(tags); 语句时,它按预期工作。看来 setTags 函数正在导致效果挂钩更新,但 tags 不是此效果挂钩的依赖项的一部分。

仅供参考,tags 变量应该是一个对象列表。

编辑:

我的代码中还有一个 useEffect

useEffect(() => { // Update which tags are logged
  if(plc != null) {
    anotherAjaxFunction(plc,tags).catch(err => {
      toaster.show({
        message: err,intent: "danger"
      });
    }).then(tags => {
      setTags(tags);
    });
  }
},[plc,updateLoggedFlag]);

但是,此 useEffect 不依赖于 tags,如果我删除代码块,问题仍然存在。

附注: updateLoggedFlag 是我计划用来强制效果根据需要更新的变量,但我还没有在任何地方使用它。

一个编辑:使用代码沙箱复制的链接https://codesandbox.io/s/cranky-ives-3xyrq?file=/src/App.js

有什么想法吗?感谢您的帮助。

解决方法

简而言之:将 TagColumn 移到 App 之外,因为它是 here


问题与效果声明无关,而是由组件声明引起的。

在您的沙箱中,TagColumn 是在 App 内定义的。这意味着每次呈现 App 时(特别是每次更改其状态时),都会为 const TagColumn 分配不同的值。 React 无法每次都看到它是同一个组件 - 毕竟,它并不真正相同,因为捕获的范围正在发生变化。
因此,App 呈现一个新的 TagColumn。 React 看到组件是从头开始创建的,渲染它,特别是调用它的钩子,包括每个 useEffect。在 useEffect 中,您使用回调来更改 App 的状态。 App 重新渲染,创建又一个 组件TagColumn,它在其生命周期中第一次再次渲染,调用每个useEffect...并且循环继续.

通常,您不应在功能组件范围内捕获任何非常量的内容。相反:

  • 如果值是由外部上下文生成的(在本例中为 App) - 将其作为 props 传递;
  • 如果值是由组件本身生成的 - 根据需要使用 useStateuseRef 或其他钩子。
,

我认为您的代码的问题在于它不包含依赖项数组中的标签。从概念上讲,这应该可以正常工作,正如其他开发人员之前提到的,但是 React 文档指出,回调中使用的所有状态变量和道具都应该存在于依赖数组中,否则会导致错误。看看这里。 Hooks FAQ

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。