useState 有自己的记忆吗?

useState has its own memoazation?

提问人:kristina malozh 提问时间:9/16/2023 最后编辑:kristina malozh 更新时间:9/16/2023 访问量:43

问:

我遇到了一个与 React Hooks 和状态管理相关的警告,我想更好地理解。我有两个代码示例,我很好奇为什么一个会触发警告而另一个不会。 代码示例一

import React, { useEffect, useState } from "react";

const Page = () => {
  let obj = { name: "sahand", age: true };
  const [count, setCount] = useState(0);

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

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount((prev) => prev + 1)}>click</button>
    </div>
  );
};

export default Page;

代码示例 2:

import React, { useEffect, useState } from "react";

const Page = () => {
  const [stateObj, setStateObj] = useState({ name: "sahand", age: true });
  const [count, setCount] = useState(0);

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

  return (
    <div>
      <h1>{count}</h1>
      <button onClick={() => setCount((prev) => prev + 1)}>click</button>
    </div>
  );
};

export default Page;

在第一个示例中,使用变量 obj 初始化 useEffect 的依赖数组会触发以下警告: ` 'obj' 对象使 useEffect Hook(第 7 行)的依赖关系在每次渲染时都发生变化。将其移动到 useEffect 回调中。或者,将 'obj' 的初始化包装在它自己的 useMemo() Hook.eslintreact-hooks/exhaustive-deps 中

` 但是,在第二个示例中,我使用 useState 定义状态,没有警告。

我知道它关于JS中的refrece类型 我的问题是:

为什么第一个带有 let obj 的代码示例会触发有关 useEffect 中依赖数组的警告?在这种情况下,在 useState 之外初始化 obj 有什么意义?

为什么第二个代码示例(我使用 useState 进行状态初始化)不触发警告?与第一个示例相比,这里的行为有什么不同?

我将不胜感激有关这些行为差异以及 React 如何处理这两种情况下的依赖关系的任何见解或解释。谢谢!据我了解,当您在useState中定义引用类型变量(例如对象或数组)时,React旨在保持对同一对象的引用,只要您不使用useState提供的setState函数显式更改它。这意味着 React 不会在每次重新渲染时将这些变量视为新的引用。

reactjs 对象 react-hooks

评论

0赞 Axnyff 9/16/2023
我认为帖子的粗体部分几乎可以回答这个问题。useState 中的内容仅在第一次渲染时计算,并保留引用,这可以防止在第二次渲染时重新渲染

答:

0赞 OMartinez-NeT 9/16/2023 #1

正如 Axnyff 所提到的,在挂载组件时只初始化一次对象,因此它可以用作依赖项。在第二个示例中,仅当更改为 时,效果才会执行。这与第一种情况相反,第一种情况在每次渲染组件时都会初始化。因此,第二个示例中的 useEffect 实质上等同于以下内容:useStateuseEffectobjsetStateObjobj

useEffect(() => {
    console.log('Printed every render')
}); 

请注意,在这种情况下,我没有添加为依赖项,因为它不是必需的。由于每次重新渲染都会创建(这是非最佳的),因此您需要确保仅在状态更改时调用效果。objobj

useState 有自己的记忆

所以我认为可以公平地说它有自己的记忆,因为它保持渲染之间的状态useState