试图确切地了解当我使用useEffect时发生了什么



我对 React 还很陌生,并试图围绕钩子来包扎我的头。 我现在正在搞砸一个非常简单的反例,使用 console.log(( 来尝试了解幕后发生的事情:

import React, { useState, useEffect } from 'react'
const Counter = () => {
const [ count, updateCount ] = useState(0)
console.log(count)
useEffect(() => {
updateCount(10)
console.log(count) 
}, [count])
return (
<div>
<h1>Counter</h1>
<div>
<button onClick={() => updateCount(count-1)}>-</button>
<span>{count}</span>
<button onClick={() => updateCount(count+1)}>+</button>
</div>
</div>
)
}

当我加载此页面时,我看到 0、0、10、10、10 记录到控制台。 据我了解,这就是正在发生的事情:

  1. 呈现组件,将默认值count设置为 0。
  2. 然后按照第 5 行将 0 记录到控制台
  3. useEffect总是在组件首次呈现时执行,而不考虑其依赖项(对吗?(,因此它会执行updateCount(10)
  4. 在状态从updateCount(10)实际更新之前,0 按照第 9 行记录到控制台
  5. count更新,因为updateCount(10). 由于状态已更改,因此组件将重新呈现。按照第 5 行再次将 10 记录到控制台
  6. 由于count被列为useEffect的依赖项,并且count已更改,因此useEffect再次执行。
  7. 再次调用updateCount(10),尽管它不应该执行任何操作,因为count已经是 10
  8. 10 再次记录到控制台,如第 9 行所示。
  9. 这样,从第 5 行开始,还有 10 个记录到控制台。 我很困惑为什么再次执行。 上次调用useEffect时,它再次将count设置为 10,但由于count已经设置为 10,组件应该不需要重新渲染,那么为什么再次执行第 5 行呢? 或者每次更新时都会重新渲染组件 状态被调用,无论状态的属性是否实际更改?

您看到第三个 10 个注销的原因是因为并发的反应实现细节中的一个怪癖。

https://github.com/facebook/react/issues/17474

通常,如果 setState 严格相等,则组件不会重新渲染:updateCount(prevState => prevState)

但是,如果状态值有任何歧义(由于并发性(,react 需要做一个"第二个"渲染,以确保状态值是相同的。

这绝对是一个有趣的怪癖,并表明您永远不应该依赖组件渲染的次数。

相关内容

  • 没有找到相关文章

最新更新