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 而不是使用 componentDidMount
或 componentDidUpdate
所以在上述情况下,当您重新加载它时,它的行为类似于 componentDidMount
,而在第二种情况下,当组件已经安装并且您导航回来时,它的行为类似于 @987654329 @。
如果您认真对待控制台日志,我会说 useEffect 在异步问题中调用回调(第一个参数)
from the react doc
与
componentDidMount
或componentDidUpdate
不同,使用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 功能