当状态改变时,useState 和 useEffect 是否也更新了?

时间:2021-04-09 02:22:31

标签: javascript reactjs

当状态改变时,组件更新到什么程度?假设当状态A发生变化时,我可以读取Component中render的控制台日志。我想知道语句 useState 会发生什么,因为初始值设置为 1,因为不应忽略初始值。当我调用 someFunction 时,a 现在变为 2,但如果发生重新渲染,const [a,setA] = useState(1) 会发生什么?

对于useEffect,当状态A改变时,我也认为useEffect会被重新声明(当然,依赖已经改变了!),但是之前声明的useEffect版本会发生什么变化?

每当我单击按钮时,都会生成新版本的 useState 和 useEffect,这些对的旧版本会怎样?它们是否被存储到浏览器的某种内存中?从 react 调试器来看,我们可以使用先前的状态值导航到先前的外观,这意味着状态的快照以某种方式存储。我超级好奇他们在哪里!如果是这样,当一定数量的状态变化超过内存限制时,我们的应用会陷入危机吗?

期待收到有关此问题的任何反馈!

const Component = () => {
  console.log('render component');
  const [a, setA] = useState(1);
  
  const someFunction = () => {
    console.log('some function')
    setA(prev=>prev+1)
  }

  useEffect(() => {
    console.log('use effect')  
    console.log(a);
  }, [a])
 
  return <>
    <div onClick={someFunction}>Click</div>
  </>
  
}

2 个答案:

答案 0 :(得分:1)

<块引用>

由于不应忽略初始值而将初始值设置为 1,因此语句 useState 会发生什么

当一个组件第一次挂载时,它内部使用的任何 useState 都会创建一个映射到 React 内部状态的值。其初始值是传递给 useState 的参数。它可能像一个数组。例如,如果您有

const [a, setA] = useState(1);
const [b, setB] = useState(5);

然后,一旦组件呈现,React 就会在内部存储类似

[1, 5]

对应第一和第二状态。

当您设置 state 时,React 内部的相应值会发生变化。例如,如果你跑了一次:

setA(prev=>prev+1)

React 就会有

[2, 5]

然后组件将重新渲染。在重新渲染时,初始状态(传递给 useState)被忽略 - 相反,有状态的值取自 React 内部的值。所以与

const [a, setA] = useState(1);
const [b, setB] = useState(5);

重新渲染时,a 的计算结果为 2,而 b 的计算结果为 5。

<块引用>

这些对的旧版本会怎样?

旧的可能会被垃圾回收,如果没有任何东西可以再引用它们。 (状态设置器函数是稳定的。)

<块引用>

对于useEffect,当状态A改变时,我也认为useEffect会被重新声明(当然,依赖已经改变了!),但是之前声明的useEffect版本会发生什么变化?

是的,对于新的渲染,之前的 useEffect 回调函数最终会被垃圾回收,React 在内部用当前渲染的新效果回调函数替换它们。

<块引用>

当一定数量的状态变化超过内存限制时,我们的应用会陷入危机吗?

否,因为之前渲染中未使用的对象会被垃圾回收。

当内存中堆积了足够多的对象并且它们被垃圾收集时,以下代码段将记录 Just got GC'd!

const r = new FinalizationRegistry(() => {
  console.log('Just got GCd!');
});

const App = () => {
    const [someObj, setSomeObj] = React.useState({ num: 0 });
    setTimeout(() => {
        r.register(someObj);
        setSomeObj({ num: someObj.num + 1 });
    }, 100);
    return JSON.stringify(someObj);;
};

ReactDOM.render(<App />, document.querySelector('.react'));
<script crossorigin src="https://unpkg.com/react@16/umd/react.development.js"></script>
<script crossorigin src="https://unpkg.com/react-dom@16/umd/react-dom.development.js"></script>
<div class='react'></div>

答案 1 :(得分:0)

<块引用>

传递给 useState 的参数是初始状态,很像设置 类组件的构造函数中的状态,不用于更新 重新渲染的状态

如果你想在 prop 变化时更新状态,请使用 useEffect 钩子

React.useState does not reload state from props