首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >理解useEffect()行为和额外的重呈现

理解useEffect()行为和额外的重呈现
EN

Stack Overflow用户
提问于 2022-01-19 10:39:26
回答 3查看 133关注 0票数 2

我对以下虚拟组件进行了一些测试,在执行过程中(在控制台中),我得到了以下结果:

代码语言:javascript
复制
Rendering:  0
Triggered:  0
Rendering:  4
Triggered:  4
Rendering:  4

我很难理解为什么。

首次渲染:

  • index设置为0
  • 运行useEffect,因为undefined不是0
  • useEffect请求将index设置为4

第二次渲染:

  • index4
  • 为什么useEffect身体会再次被执行?

第三次渲染:

  • 为什么要重新渲染?

我期望的是:

代码语言:javascript
复制
Rendering:  0
Triggered:  0
Rendering:  4

我是不是跳过了很明显的东西?你能帮我理解一下引擎盖下的工作原理吗?

代码语言:javascript
复制
const Example = React.memo(() => {
    const [index, setIndex] = React.useState(0)
    console.log('Rendering: ', index)

    React.useEffect(() => {
        console.log('Triggered: ', index)
        setIndex(4)
    }, [index])

    return <h1>{index}</h1>
})

ReactDOM.render(<Example />, document.body);
代码语言:javascript
复制
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/17.0.2/umd/react.production.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react-dom/17.0.2/umd/react-dom.production.min.js"></script>

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2022-01-19 10:46:27

重发的数量实际上是正确的。让我们分析一下发生了什么:

  1. 呈现0 -这是在挂载第一个呈现(在这种状态下,每个useEffect自动运行)
  2. 触发0 -这是useEffect的初始触发
  3. 呈现4 -此重命名器是因为您将index的新状态设置为4
  4. 触发了4 -这是因为您将index从0更改为4
  5. 呈现4 -这是因为状态从4更改为4 (即使值相同,它也会触发组件重发,因为React不知道是否设置了相同的状态,并且需要再次运行)。在这个重命名器中,useEffect不会运行,因为index又是4了。

基本原理

如果组件中有任何变化,比如useState useContextcustomHook,则该组件将需要重命名。如果父组件重选器,即使组件没有任何更改,子组件也会发生这种情况。

更多的更新提示和信息

为了防止子组件发生父级不必要的重命名,您可以使用React.memo,如果道具发生更改,这将重新更新组件,但如果状态或上述任何挂钩在组件中发生更改,则不会阻止组件重命名。

如果这看起来是多余的,听起来就像它,但它是必要的,所以这种反应是肯定的,它有最新的状态。像这样运行JS比拥有一些状态内存来检查更改更快,而且对于开发人员来说也更透明(以及VDOM是如何实现的)。

票数 4
EN

Stack Overflow用户

发布于 2022-01-19 10:54:35

预期的产出无法实现。

useEffect在组件挂载时呈现,在每次状态更改时重新呈现(索引)。

代码语言:javascript
复制
const Example = () => {
    const [index, setIndex] = React.useState(0)
    console.log('Rendering: ', index)
    React.useEffect(() => {
        console.log('Triggered: ', index)
        setIndex(4)
    }, [index])

    return <h1>{index}</h1>
}

输出:

  • 呈现: 0 =>当组件首次挂载时,该时间索引为0
  • 触发:安装useEffect触发器上的0 =>,状态更新(0到4)
  • 呈现: 4 => Componet重新呈现,因为状态已从(0 )更改为4
  • 触发: 4 => useEffect重新触发,因为状态已更改(0到4)
  • 呈现: 4 => Componet重新呈现,因为为了检查状态是否已经更改(4到4,类型的确认没有改变)
票数 2
EN

Stack Overflow用户

发布于 2022-01-19 10:55:18

useEffect的工作方式只有在呈现页面组件之后才能运行。

希望这能帮助你理解。

第一个渲染索引为0。

代码语言:javascript
复制
Rendering:  0

它触发useEffect。

代码语言:javascript
复制
Triggered:  0

索引在useEffect中更新,而在组件中没有更新。然后呈现将索引更新为4。

代码语言:javascript
复制
Rendering:  4

useEffect运行是因为索引已经更改。

代码语言:javascript
复制
Triggered:  4

组件将再次呈现,但索引仍然是4,因此useEffect不会再次运行。

代码语言:javascript
复制
Rendering:  4
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/70769126

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档