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

IT技术 reactjs use-effect
2021-04-15 01:45:43

例如,如果我有组件 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()子组件方法先于父组件调用。

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

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

2个回答

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

<A>
 <B />
</A>

然后在第一次加载 (Reload) 日志中

儿童B使用效果

父 A 使用效果

然后假设您导航到某个路线,然后转到子组件日志将是

儿童B使用效果

不会调用父 useEffect。

正如react文档所说

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

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

沙箱让您了解 useEffect 是如何调用的,它有 Roster 作为父级,Schedule 作为子级。如果您导航到 Header 并返回到 Schedule 只有它的 useEffect 被调用。

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

希望能帮助到你

如果你想useEffect表现得像在componentDidMount()刚刚通过[]的回调参数后的第二个参数。

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

所以useEffect引入,而不是使用 componentDidMountcomponentDidUpdate在当重新加载其工作方式类似于上面的情况,从而 componentDidMount与在所述第二情况下,当部件已经被安装和你导航支持它的行为就像 componentDidUpdate

如果您对控制台日志很认真,我会说 useEffect 在异步问题中调用回调(第一个参数)

来自react文档

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

谢谢您的回答。但是你能不能更新一下,让它更容易理解?情况1(重新加载后)的原因是什么,情况2(使用react-router)的原因是什么?
2021-06-09 01:45:43
@HoangTrinh 我也遇到过类似的问题。但不同的是,我的控制台总是显示相同的顺序 case 1 和 case 2。此外,我可以在您的 react doc 链接中找到为什么子组件总是执行 useEffect 的答案。谢谢!希望你能找到答案。
2021-06-14 01:45:43