reactjs React父组件和子组件中useEffect的正确执行顺序是什么?

fumotvh3  于 2023-02-22  发布在  React
关注(0)|答案(3)|浏览(330)

例如,如果我有零部件A和B,并且零部件B是零部件A的子项:

<A>
  <B />
</A>

在A中我们有:

useEffect(() => {
  console.log('Parent A useEffect')
})

在B中我们有:

useEffect(() => {
  console.log('Child B useEffect')
})

我做了一些测试,我看到两件事:
1.在第一次加载时(例如,F5之后),日志结果为:
父项A使用效果
儿童B使用效果
1.如果我们转到另一个组件,然后返回到组件B(例如,不是通过重新加载,而是通过使用react-router),则日志结果为:
儿童B使用效果
父项A使用效果
有两种情况,结果是相反的,这让我有点困惑。
我搜索谷歌关于componentDidMount,我发现这个:https://github.com/facebook/react/blob/v15.0.1/docs/docs/ref-03-component-specs.md#mounting-componentdidmount
子组件的componentDidMount()方法在父组件的componentDidMount()方法之前调用。
但是找不到useEffect对应的文档

那么,useEffect在父/子组件中的正确执行顺序是什么?

am46iovg

am46iovg1#

好的,我会尽力澄清你的困惑。如果你有一些像这样的组件

<A>
 <B />
</A>

然后,在第一次加载(重新加载)时,日志将
儿童B使用效果
父项A使用效果
假设您导航到某个路径,然后转到子组件日志
儿童B使用效果
不会调用父级useEffect。
就像医生说的
您可以将使用效果挂钩视为组件DidMount、组件DidUpdate和组件WillUnmount的组合。
因此,所有这些生命周期方法都是在装入组件之后调用的,并且在装入组件时,该组件内部的子组件已经装入,并且它们的生命周期已经调用
Sandbox让您了解如何调用useEffect,它将Roster作为父项,将Schedule作为子项。如果您导航到Header并返回Schedule,则仅调用它的useEffect。
在您的示例中,当您导航到子组件时,可能会调用Parent useEffect,但这是由于其他原因,可能您有一些回调函数来设置Parent state,从而导致调用它的useEffect,但我们讨论的是useEffect在一般情况下的工作方式
希望能有所帮助

vlju58qv

vlju58qv2#

我知道这是旧的,但我会把我的答案,以防我在未来再次访问它。
useEffect的默认执行顺序可以表示为:
如果我们有三个元素,并且其中三个调用useEffect钩子,则执行顺序为:

<ThirdExecuted>
  <SecondExecuted>
    <FirstExecuted>
    </FirstExecuted>
  </SecondExecuted>
</ThirdExecuted>

并且执行将在渲染完成后发生。因此,如果需要手动修改节点(比如添加动画),可以安全地从中选择节点。
但是,如果需要先调用父级useEffect,则应该使用useLayoutEffect

1l5u6lss

1l5u6lss3#

如果你想让useEffectcomponentDidMount()一样工作,只需将[]作为回调参数之后的第二个参数传递。

useEffect(()=>{
// this we executed once the component is mounted (mimic the componentDidMount)
},[])

因此,引入了useEffect,而不是使用componentDidMountcomponentDidUpdate,因此在上述情况下,当您重新加载时,其行为类似于componentDidMount,而在第二种情况下,当组件已安装且您向后导航时,其行为类似于componentDidUpdate
如果你是认真的控制台日志的,我会说useEffect调用回调(第一个参数)在异步的事情
来自React文件
componentDidMountcomponentDidUpdate不同,使用useEffect计划的效果不会阻止浏览器更新屏幕。这会让你的应用感觉更灵敏。大多数效果不需要同步发生。

相关问题