例如,如果我有零部件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
在父/子组件中的正确执行顺序是什么?
3条答案
按热度按时间am46iovg1#
好的,我会尽力澄清你的困惑。如果你有一些像这样的组件
然后,在第一次加载(重新加载)时,日志将
儿童B使用效果
父项A使用效果
假设您导航到某个路径,然后转到子组件日志
儿童B使用效果
不会调用父级useEffect。
就像医生说的
您可以将使用效果挂钩视为组件DidMount、组件DidUpdate和组件WillUnmount的组合。
因此,所有这些生命周期方法都是在装入组件之后调用的,并且在装入组件时,该组件内部的子组件已经装入,并且它们的生命周期已经调用
Sandbox让您了解如何调用useEffect,它将Roster作为父项,将Schedule作为子项。如果您导航到Header并返回Schedule,则仅调用它的useEffect。
在您的示例中,当您导航到子组件时,可能会调用Parent useEffect,但这是由于其他原因,可能您有一些回调函数来设置Parent state,从而导致调用它的useEffect,但我们讨论的是useEffect在一般情况下的工作方式
希望能有所帮助
vlju58qv2#
我知道这是旧的,但我会把我的答案,以防我在未来再次访问它。
useEffect
的默认执行顺序可以表示为:如果我们有三个元素,并且其中三个调用
useEffect
钩子,则执行顺序为:并且执行将在渲染完成后发生。因此,如果需要手动修改节点(比如添加动画),可以安全地从中选择节点。
但是,如果需要先调用父级
useEffect
,则应该使用useLayoutEffect
。1l5u6lss3#
如果你想让
useEffect
像componentDidMount()
一样工作,只需将[]
作为回调参数之后的第二个参数传递。因此,引入了useEffect,而不是使用
componentDidMount
或componentDidUpdate
,因此在上述情况下,当您重新加载时,其行为类似于componentDidMount
,而在第二种情况下,当组件已安装且您向后导航时,其行为类似于componentDidUpdate
。如果你是认真的控制台日志的,我会说useEffect调用回调(第一个参数)在异步的事情
来自React文件
与
componentDidMount
或componentDidUpdate
不同,使用useEffect
计划的效果不会阻止浏览器更新屏幕。这会让你的应用感觉更灵敏。大多数效果不需要同步发生。