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

Posted

技术标签:

【中文标题】React父子组件中useEffect的正确执行顺序是啥?【英文标题】:What is the correct order of execution of useEffect in React parent and child components?React父子组件中useEffect的正确执行顺序是什么? 【发布时间】:2020-02-09 15:18:40 【问题描述】:

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

<A>
  <B />
</A>

在 A 里面我们有:

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

在 B 中我们有:

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

我做了一些测试,我看到了两件事:

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

父A useEffect

儿童 B 使用效果

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

儿童 B 使用效果

父A useEffect

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

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

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

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

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

【问题讨论】:

【参考方案1】:

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

<A>
 <B />
</A>

那么在第一次加载(Reload)日志就会

儿童 B 使用效果

父A useEffect

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

儿童 B 使用效果

不会调用父 useEffect。

正如反应文档所说

你可以把useEffect Hook想象成componentDidMount、componentDidUpdate和componentWillUnmount的组合。

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

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

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

希望对你有帮助

【讨论】:

【参考方案2】:

如果您希望useEffect 的行为类似于componentDidMount(),只需将[] 作为回调参数之后的第二个参数传递。

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

所以引入了 useEffect 而不是使用 componentDidMountcomponentDidUpdate 所以在上述情况下,当您重新加载它时,它的行为类似于 componentDidMount,而在第二种情况下,当组件已经安装并且您导航回来时,它的行为类似于 @987654329 @。

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

from the react doc

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

【讨论】:

感谢您的回答。但是您能否更新它以更容易理解? case 1(重新加载后)是什么原因,case 2(使用react-router)是什么原因? @HoangTrinh 我遇到了类似的问题。但不同的是,我的控制台总是显示相同的订单 case 1 和 case 2。此外,我可以在你的 react doc 链接中找到为什么子组件总是执行 useEffect 的答案。谢谢!希望你能找到答案。

以上是关于React父子组件中useEffect的正确执行顺序是啥?的主要内容,如果未能解决你的问题,请参考以下文章

React useEffect 抛出错误:无法对未安装的组件执行 React 状态更新

无法对未安装的组件执行 React 状态更新(useEffect 反应挂钩)

React:“无法在未安装的组件上执行 React 状态更新”,没有 useEffect 功能

React hooks之useEffect

React Hooks --- useState 和 useEffect

react父子组件生命周期执行顺序