当前位置: 首页 > 知识库问答 >
问题:

在状态变化时的反应中,useState和use效应是否也更新了?

曾丰茂
2023-03-14

当状态更改时,组件的更新程度如何?比方说,当状态A发生变化时,我可以读取render in组件的控制台日志。我想知道useState语句会发生什么情况,因为初始值设置为1,因为不应该忽略初始值。当我调用某个函数时,a现在变为2,但如果发生重新排序,const[a,setA]=useState(1)会发生什么情况?

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

每当我点击按钮时,就会生成新版本的useState和use效应,这些对的旧版本会发生什么?它们被存储在浏览器的某种内存中吗?从响应调试器判断,我们可以导航到以前的状态值,这意味着状态的快照以某种方式存储。我超级好奇他们在哪里!如果这是真的,当特定数量的状态更改超过内存限制时,我们的应用程序会陷入危机吗?

期待得到任何关于这个问题的反馈!

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个答案

颜鸿云
2023-03-14

传递给useState的参数是初始状态,非常类似于在类组件的构造函数中设置状态,并且不用于在重新呈现时更新状态

如果您想更新道具更改的状态,请使用use效果钩子

React.use状态不会从道具重新加载状态

龙佐
2023-03-14

由于初始值设置为1,因为初始值不应该被忽略,所以语句useState会发生什么

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

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

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

[1, 5]

对应于第一和第二状态。

设置状态时,React内部的相应值会发生变化。例如,如果您运行了一次:

setA(prev=>prev+1)

反应会有

[2, 5]

然后组件将重新渲染。在重新呈现时,将忽略初始状态(传递给useState),相反,状态值取自React internal中的值。所以

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

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

这些配对的旧版本发生了什么?

如果没有任何东西可以再引用旧值,则旧值可能会被垃圾收集。(状态设置器功能稳定。)

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

是的,使用新的渲染,先前的use效应回调函数最终会被垃圾收集,React在内部用当前渲染的新效果回调函数替换它们。

当特定数量的状态更改超过内存限制时,我们的应用程序会陷入危机吗?

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

下面的代码片段将记录刚刚得到的GC 当足够多的对象堆积在内存中并被垃圾回收时:

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>
 类似资料:
  • 问题内容: 在这里,我尝试设置为’hello’,然后打印它,但是状态似乎为空。当我刚刚使用更新状态时怎么办?设置为全局变量。 问题答案: 从reactjs文档中: 不会立即变异,但会创建待处理的状态转换。调用此方法后进行访问可能会返回现有值。 https://facebook.github.io/react/docs/component- api.html 您可以做的是将状态更新后传递给回调函数:

  • 问题内容: 我处于状态的对象数组: 我需要能够基于id属性搜索items数组,然后更新对象属性。 我可以使用id参数通过数组或在数组上获取对象。 我遇到的麻烦是更新数组,然后更新状态而不会发生突变。 此时,我有一个匹配的对象,可以使用对象传播来更新它的属性: 我的问题是我该如何更新状态,以使其覆盖初始查找操作返回的对象? 问题答案: 您的更新功能如下所示 你这样使用它 毛吧? 如果您继续以这种方式

  • 问题内容: 所以我有这个: newDealersDeckTotal只是一个数字数组,例如,但是没有给出正确的总数,但是呢?我什至设置了超时延迟,以查看是否可以解决问题。任何明显的还是我应该发布更多代码? 问题答案: 通常是异步的,这意味着在您处于状态时,它尚未更新。尝试将日志放入方法的回调中。状态更改完成后执行:

  • 因此,我有一些代码并没有像预期的那样工作。当前焦点是在父组件上使用useState()设置的,因此它是一个状态变量。但是,当父级中的currentFocus值更改时,此处的focus变量本身不会更新。我希望重新呈现父组件,这反过来会重新呈现该组件,从而导致foucs值发生更改。 现在我可以通过执行以下操作来解决此问题, 但我只想在更新focus/currentFocus时运行useEffect挂钩

  • 我正在尝试新的hooks功能,并坚持认为我的状态没有更新。 实际上,状态已更新(我可以在console.log中看到更新的值,并且我的组件会重新运行useEffect),但是useEffect方法使用我的旧状态,并仅将签名保存给第一个用户,而活动用户在状态中确实发生了更改。 我想过添加useCallback,并将我的方法移动到use效果或组件本身,但我可以设法让它工作。 状态: 这是我的效果: 这