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

时间:2019-10-12 08:40:08

标签: reactjs use-effect

例如,如果我有组件A和B,而组件B是组件A的子代:

<A>
  <B />
</A>

在A内,我们有:

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

在B内,我们有:

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

我做了一些测试,发现了两件事:

  1. 在第一次加载时(例如,在F5之后),日志结果为:
  

父母A useEffect

     

儿童B useEffect

  1. 如果我们转到另一个组件,然后回到组件B(例如,不是通过重新加载而是通过使用react-router),则日志结果为:
  

儿童B useEffect

     

父母A useEffect

在两种情况下,结果相反。这让我有些困惑。

我在Google上搜索了componentDidMount,发现了这个内容:https://github.com/facebook/react/blob/v15.0.1/docs/docs/ref-03-component-specs.md#mounting-componentdidmount

  

子组件的componentDidMount()方法在调用之前   父组件的值。

但是我找不到关于useEffect的相应文档

那么{/ {1}}在父/子组件中的正确执行顺序是什么?

2 个答案:

答案 0 :(得分:2)

如果您希望useEffect的行为像componentDidMount(),则只需将[]作为回调参数之后的第二个参数即可。

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

因此引入了useEffect而不是使用componentDidMountcomponentDidUpdate,因此在上述情况下,当您重新加载时,其行为类似于componentDidMount;在第二种情况下,当组件已经安装并导航时回到它的行为就像componentDidUpdate

如果您对控制台日志很认真,我会说useEffect调用异步事件中的callback(第一个参数)

  

from the react doc

     

componentDidMountcomponentDidUpdate不同,使用useEffect安排的效果不会阻止浏览器更新屏幕。这使您的应用程序感觉更灵敏。大多数效果不需要同步发生。

答案 1 :(得分:2)

好的,我会尽力消除您的困惑。 如果您有类似这样的组件

<A>
 <B />
</A>

然后在第一个加载(重新加载)日志中

  

儿童B useEffect

     

父母A useEffect

然后可以说您导航到某个路线,然后转到“子组件日志将是

  

儿童B useEffect

     

不会调用父useEffect。

正如反应文档所说

  

您可以将useEffect Hook视为componentDidMount,componentDidUpdate和componentWillUnmount的组合。

因此,所有这些生命周期方法都在安装组件之后调用,并且在安装组件时,已经安装了该组件内部的子组件,并且它们的lifeCycle已经被调用

Sandbox让您了解如何调用useEffect,它以Roster为父级,Schedule为子级。如果您导航到Header并仅返回Schedule,则将调用useEffect。

在您的情况下,当您导航到子组件时,可能会调用Parent useEffect,但这是由于其他原因,也许您有一些回调设置了Parent状态,从而导致了useEffect被调用,但是我们正在谈论如何useEffect通常可以正常工作

希望有帮助