Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【Q474】在 react 中,以下父子组件的 useEffect/useLayoutEffect 顺序如何 #802

Open
shfshanyue opened this issue Sep 27, 2023 · 1 comment
Labels

Comments

@shfshanyue
Copy link
Owner

shfshanyue commented Sep 27, 2023

以下代码在控制台里如何按序输出,代码见 codesandbox

import { useEffect, useLayoutEffect } from "react";
import "./App.css";

function Child() {
  console.log("Child: Render");

  useEffect(() => {
    console.log("Child: useEffect");
  });

  useLayoutEffect(() => {
    console.log("Child: useLayoutEffect");
  });

  return <div className="App">Child</div>;
}

function App() {
  console.log("App: render");

  useEffect(() => {
    console.log("App: useEffect");
  });

  useLayoutEffect(() => {
    console.log("App: useLayoutEffect");
  });

  return (
    <div className="App">
      App
      <Child />
    </div>
  );
}

export default App;
@wangfengyuan
Copy link

wangfengyuan commented Sep 28, 2023

不太会,跑了下,运行结果如下
https://stackblitz.com/edit/vitejs-vite-ibcjhf?file=src%2FApp.jsx

App: render
Child: Render
Child: useLayoutEffect
App: useLayoutEffect
Child: useEffect
App: useEffect

学习了下面两篇文章:
https://jser.dev/2023-07-08-how-does-useeffect-work
https://jser.dev/react/2021/12/04/how-does-useLayoutEffect-work

总结一下我的理解:
1、useEffect 通过 scheduleCallback调度的,是异步执行的,也就是在渲染到页面后执行
而useLayoutEffect 是同步执行的,发生在dom mutation更新了dom结构,但是还未绘制到屏幕之前
2、useEffect 和 useLayoutEffect 都是递归执行的,先执行子组件
3、有useEffect 和 useLayoutEffect的fiber会被打上标记,加入到effectList中, 每次更新都会都会处理, 两个函数都会处理成effectObject, 包含create、destory属性,其中create是useEffect 和 useLayoutEffect传入的函数,destory对应传入的函数执行返回的函数,在commit阶段,每次都是先执行destory清理函数,然后执行create, 挂载时destory为undefined,跳过清理函数执行,执行create,执行后把return的函数复制给destory, 下一次更新时destory不为undefined就会执行destory销毁函数,如果dep有变化接下来执行create

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants