【问题标题】:How to prevent infinite loop in my React code when using setState inside useEffect在useEffect中使用setState时如何防止我的React代码中的无限循环
【发布时间】:2021-02-17 14:20:53
【问题描述】:

请检查代码框:https://codesandbox.io/s/bold-hamilton-k1nzs

在我运行代码的那一刻,我得到一个无限循环,您可以检查控制台以查看条目如何呈指数增长。最终网站崩溃了。

我有一个这样的状态变量:

const [checkbox, setCheckBox] = useState({});

然后我在useEffect里面调用一个函数:

useEffect(() => {
    createCheckbox();
  });

这是 createCheckbox 函数:

const createCheckbox = () => {
    let checkboxObj = {};
    rows.forEach((e) => {
      checkboxObj[e.id] = false;
    });
    setCheckBox(checkboxObj);
  };

我在第 76 行有一个 console.log 来展示这个问题。它是 console.log(checkbox)

知道发生了什么吗?

【问题讨论】:

  • 我看到这个的第一个问题是,为什么你需要在 useEffect 中创建 Checkbox() ?
  • 该效果没有依赖并更新状态,所以结果是渲染循环。添加依赖项。检查条件 on 该依赖项。您希望createCheckbox 何时运行?
  • @Spangle 我上面有一个代码框。基本上我想在第一次加载时将复选框初始化为空/假。

标签: javascript reactjs material-ui


【解决方案1】:

useEffect 使用依赖数组。所以这个:

  useEffect(() => {
    createCheckbox();
  });

应该是:

  useEffect(() => {
    createCheckbox();
  }, []);

useEffect(),如您所知,接受依赖数组作为第二个参数。它只会在数组中的任何变量发生变化时运行。当您在没有第二个参数的情况下运行useEffect 时,它充当componentDidMount 和componentDidUpdate。因此,由于您在无依赖的 useEffect 中设置了一个状态,因此状态更改会一次又一次地触发它,从而创建一个无限循环的渲染。

当使用空的依赖数组调用useEffect 时,它只会在第一次渲染时运行一次。而这正是你所需要的。

【讨论】:

  • 稍微解释一下可能不会有什么坏处:)
【解决方案2】:

问题

useEffect(() => {
  createCheckbox();
});

useEffect 钩子没有依赖关系,因此它在每次组件渲染时都会运行,并且由于钩子回调最终会更新状态,它会触发另一个渲染周期。冲洗并重复,令人作呕(即渲染循环)。

解决方案

基本上我想先将复选框初始化为空/假 加载。

您可以使用带有空依赖数组的useEffect 在组件挂载时运行一次效果。

useEffect(() => {
  createCheckbox();
}, []);

或者使用带有useState钩子的惰性状态初始化函数。

const [checkbox, setCheckBox] = useState(() => {
  let checkboxObj = {};
  rows.forEach((e) => {
    checkboxObj[e.id] = false;
  });
  return checkboxObj;
});

演示

【讨论】:

  • 我运行了沙盒。出于某种原因,当我单击复选框时,它并没有被选中。但无限循环似乎消失了。
  • @Adam 这不是问题的一部分,所以除了消除渲染循环之外,我没有进行任何进一步的调试,但我不介意深入研究。
  • 谢谢,无论如何我都会将此标记为答案,并将另一个作为新问题打开。
  • @Adam 我想我已经解决了复选框不切换的问题。有新问题的链接吗?
  • 一分钟。现在提出问题
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2021-01-15
  • 1970-01-01
  • 2022-11-29
  • 2021-10-21
  • 2019-11-11
  • 2021-12-05
  • 2023-03-22
相关资源
最近更新 更多