React 父子组件中 useEffect 的正确执行顺序是什么?
What is the correct order of execution of useEffect in React parent and child components?
例如,如果我有组件 A 和 B,组件 B 是组件 A 的子组件:
<A>
<B />
</A>
在 A 里面我们有:
useEffect(() => {
console.log('Parent A useEffect')
})
在 B 里面我们有:
useEffect(() => {
console.log('Child B useEffect')
})
我做了一些测试,我看到了两件事:
- 第一次加载时(例如F5之后),日志结果为:
Parent A useEffect
Child B useEffect
- 如果我们转到另一个组件然后回到组件B(不是通过重新加载而是通过使用react-router,例如),日志结果是:
Child B useEffect
Parent A useEffect
有两种情况,结果是相反的。这让我有点困惑。
我搜索了 Google 关于 componentDidMount
的内容,我发现了这个:https://github.com/facebook/react/blob/v15.0.1/docs/docs/ref-03-component-specs.md#mounting-componentdidmount
The componentDidMount()
method of child components is invoked before
that of parent components.
但是我找不到关于useEffect
的相应文档
那么parent/child组件中useEffect
的正确执行顺序是什么?
如果您希望 useEffect
表现得像 componentDidMount()
,只需将 []
作为第二个参数传递给回调参数。
useEffect(()=>{
// this we executed once the component is mounted (mimic the componentDidMount)
},[])
所以引入了 useEffect 而不是使用 componentDidMount
或 componentDidUpdate
所以在上面的情况下当你重新加载它时表现得像 componentDidMount
并且在第二种情况下当组件已经安装并且你导航回来它的行为就像 componentDidUpdate
.
如果您认真对待控制台日志,我会说 useEffect 在异步问题中调用回调(第一个参数)
Unlike componentDidMount
or componentDidUpdate
, effects scheduled with useEffect
don’t block the browser from updating the screen. This makes your app feel more responsive. The majority of effects don’t need to happen synchronously.
好的,我会尽力消除您的困惑。
如果你有这样的组件
<A>
<B />
</A>
然后在第一次载入(Reload)日志时会
Child B useEffect
Parent A useEffect
然后假设您导航到某个路径,然后转到子组件日志将是
Child B useEffect
Parent useEffect won't be called.
正如 React 文档所说
you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.
所以所有这些生命周期方法都是在组件挂载后调用的,当组件挂载时,该组件内的子组件已经挂载并且它们的生命周期已经被调用
Sandbox 让您了解如何调用 useEffect,它有 Roster 作为 Parent,Schedule 作为 child。如果您导航到 Header 并仅返回到 Schedule,则会调用 useEffect。
在您的情况下,当您导航到子组件时,可能会调用 Parent useEffect,但这是由于其他原因,也许您有一些设置 Parent 状态的回调,从而导致调用 useEffect,但我们正在讨论关于 useEffect 在一般情况下的工作原理
希望对您有所帮助
例如,如果我有组件 A 和 B,组件 B 是组件 A 的子组件:
<A>
<B />
</A>
在 A 里面我们有:
useEffect(() => {
console.log('Parent A useEffect')
})
在 B 里面我们有:
useEffect(() => {
console.log('Child B useEffect')
})
我做了一些测试,我看到了两件事:
- 第一次加载时(例如F5之后),日志结果为:
Parent A useEffect
Child B useEffect
- 如果我们转到另一个组件然后回到组件B(不是通过重新加载而是通过使用react-router,例如),日志结果是:
Child B useEffect
Parent A useEffect
有两种情况,结果是相反的。这让我有点困惑。
我搜索了 Google 关于 componentDidMount
的内容,我发现了这个:https://github.com/facebook/react/blob/v15.0.1/docs/docs/ref-03-component-specs.md#mounting-componentdidmount
The
componentDidMount()
method of child components is invoked before that of parent components.
但是我找不到关于useEffect
那么parent/child组件中useEffect
的正确执行顺序是什么?
如果您希望 useEffect
表现得像 componentDidMount()
,只需将 []
作为第二个参数传递给回调参数。
useEffect(()=>{
// this we executed once the component is mounted (mimic the componentDidMount)
},[])
所以引入了 useEffect 而不是使用 componentDidMount
或 componentDidUpdate
所以在上面的情况下当你重新加载它时表现得像 componentDidMount
并且在第二种情况下当组件已经安装并且你导航回来它的行为就像 componentDidUpdate
.
如果您认真对待控制台日志,我会说 useEffect 在异步问题中调用回调(第一个参数)
Unlike
componentDidMount
orcomponentDidUpdate
, effects scheduled withuseEffect
don’t block the browser from updating the screen. This makes your app feel more responsive. The majority of effects don’t need to happen synchronously.
好的,我会尽力消除您的困惑。 如果你有这样的组件
<A>
<B />
</A>
然后在第一次载入(Reload)日志时会
Child B useEffect
Parent A useEffect
然后假设您导航到某个路径,然后转到子组件日志将是
Child B useEffect
Parent useEffect won't be called.
正如 React 文档所说
you can think of useEffect Hook as componentDidMount, componentDidUpdate, and componentWillUnmount combined.
所以所有这些生命周期方法都是在组件挂载后调用的,当组件挂载时,该组件内的子组件已经挂载并且它们的生命周期已经被调用
Sandbox 让您了解如何调用 useEffect,它有 Roster 作为 Parent,Schedule 作为 child。如果您导航到 Header 并仅返回到 Schedule,则会调用 useEffect。
在您的情况下,当您导航到子组件时,可能会调用 Parent useEffect,但这是由于其他原因,也许您有一些设置 Parent 状态的回调,从而导致调用 useEffect,但我们正在讨论关于 useEffect 在一般情况下的工作原理
希望对您有所帮助