【问题标题】:Do updating state of an object inside the useEffect() creates a new object?在 useEffect() 中更新对象的状态是否会创建一个新对象?
【发布时间】:2021-06-25 19:37:37
【问题描述】:
import { useEffect, useState } from "react";

function CountSecrets() {
  const [secret, setSecret] = useState({ value: "", countSecrets: 0 });

  useEffect(() => {
    if (secret.value === 'secret') {
      setSecret(s => ({...s, countSecrets: s.countSecrets + 1}));    }
  }, [secret]);
  const onChange = ({ target }) => {
    setSecret(s => ({ ...s, value: target.value }));
  };

  return (
    <div>
      <input type="text" value={secret.value} onChange={onChange} />
      <div>Number of secrets: {secret.countSecrets}</div>
    </div>
  );
}

当输入 secret 时,反应进入无限循环

我正在通过一篇博客文章阅读这段代码,其中写道在 useEffect 中设置对象的状态 创建一个新对象,因此 useEffect 的 [ ] 中的依赖项 变化并导致无限循环

这是我的问题,当我们键入并且 onchange 被触发并且也在更新状态时,更新 onchange 内部的状态是否不会创建新对象?以及创建新对象的情况是什么?

这是博客的链接(第二点)Link

【问题讨论】:

  • 它不会创建新对象。问题在于比较 JS 中的对象; 2 个对象永远不会相同,即使它们包含相同的键/值。阅读此答案:stackoverflow.com/a/66058022/1927991
  • 更新状态不会自动创建一个新对象,每次你的状态改变时,你都有责任为 React 提供一个新对象,在上述所有情况下你都会这样做。
  • 但是我正在更新状态,所以这会创建新对象吗?

标签: reactjs infinite-loop use-effect use-state


【解决方案1】:

React 中的拇指规则是状态对象是不可变的,不能直接改变它。因此,每当您想更新状态时,您总是会创建新对象。

查看您的代码,在onChangeuseEffects 两种情况下都创建了新对象。但是useEffects 会在依赖项发生变化时创建无限循环,而 onChange 不会创建无限循环,因为状态更新不会再次 onChange

如果你想避免无限循环,我建议两种方法。

  • [secret] --&gt; [secret.value]更改依赖数组
  • 或者将这 2 个值 value, countSecrets作为 2 个不同的状态

总而言之,当您将对象作为状态时,您应该始终创建新对象并设置它。至于基于值的状态,react 会处理它。

【讨论】:

  • 通过您的回答,您想说当 onChange 被触发时,它会创建新对象,然后新对象不会再次触发 onChange。虽然 useEffect 中的对象创建每次都会触发 useEffect ,因为依赖项会随着新对象的创建等而变化。
  • 绝对是的。 OnChange 不会像 useEffect 那样再次触发,因此您不会在 onChange 情况下获得无限循环
  • 感谢您的努力并消除了我的疑问:)
猜你喜欢
  • 1970-01-01
  • 2020-11-06
  • 1970-01-01
  • 1970-01-01
  • 2020-05-02
  • 2019-09-27
  • 1970-01-01
  • 2014-11-25
  • 2015-07-26
相关资源
最近更新 更多