Coder Social home page Coder Social logo

Comments (3)

creamidea avatar creamidea commented on June 24, 2024

https://react.iamkasong.com/preparation/idea.html

https://7kms.github.io/react-illustration-series/main/fibertree-update

from creamidea.github.com.

creamidea avatar creamidea commented on June 24, 2024

React 更新总结
以 FunctionComponent 组件内 useState 为例子(去掉优先级等概念)

调用 useState 返回的 set 函数,实际调用 dispatchSetState 函数(函数在首次 Fiber 树创建时,也就是第一次运行 FunctionComponent 生成,通过 bind 处理之后返回,即 set 函数),内部主要做了 2 件事:

  1. 存储更新的负载 Update 到 fiber 结构里面
  2. 调用 scheduleUpdateOnFiber 函数(所有更新函数都会进入这个函数)

scheduleUpdateOnFiber 函数内:

  1. 找到根节点 <- 这里体现了 React 的数据流是单向的,总是从 Root 开始
  2. 以根节点为参数,调用 ensureRootIsScheduled 函数

ensureRootIsScheduled

  1. 构造任务,将其放入调度器(后续讲调度器时,讲如何中断、如何恢复)
  2. 任务一般是:performSyncWorkOnRoot 或者 performConcurrentWorkOnRoot
  3. 后续的调用链,以同步为例子,一笔带过,感兴趣可以深入研究 performSyncWorkOnRoot -> renderRootSync -> workLoopSync

workLoopSync 是我们需要关注的核心函数和逻辑

  1. 以 DFS 的形式遍历 Fiber 树
  2. 递阶段,beginWork 函数:
    1. 调用 FunctionComponent(用户定义的组件),产出下一个fiber
      1. 执行 FunctionComponent 时,内部 useState 就要求返回最新的状态值。此时会读取 fiber 里 Update 结构进行计算
      2. dispatchSetState 不变,在初次渲染时就决定
    2. 新产出的 fiber 和之前的 fiber 进行比较 reconcile
      1. 单节点
      2. 多节点
    3. 如果下一个 fiber 存在,进入下一个 beginWork
    4. 如果下一个 fiber 不存在,进入归阶段,completeWork 函数
  3. 归阶段,completeWork 函数:
    1. 处理属性
    2. 补充,如果是 HostComponent(也就是原生 DOM 元素)此时会调用 createElement 函数创建处理,处理属性、样式、处理事件等

经过 workLoopSync 处理 Fiber 树之后,我们就知道了哪些节点会有副作用(对于 HostComponent 来说就是增删改 DOM 元素,对于 Function Component 来说,就是要不要执行 useEffect useLayoutEffect ref 等这些副作用)
这些副作用,存储在根节点的 firstEffect 开始的副作用链上。

下一阶段,就是将这些副作用开始「提交」,也是从根节点开始

commitRoot(root)

  1. 调度 flushPassiveEffects (用的是 scheduleCallback,这里就是异步了)
    1. 这里面就是存放的 useEffect 执行链
    2. 是否调度,看 rootDoesHavePassiveEffects 是否为 false。在 layout effects 之后,rootWithPendingPassiveEffects 被赋值 root
  2. before mutation effects
    1. 将 useEffect 注册的函数放入调度器(意味着是异步执行)
  3. mutation effects
    1. 应用副作用到 DOM 树(增删改)
    2. Detach ref
  4. 切换 root.current (可以先不关注)
  5. layout effects
    1. 执行 useLayoutEffect(先执行 destroy 函数),所以此时是可以获取到 DOM 对象
    2. Attach ref

为什么 React 的数据流是单向的?

React Fiber 喜欢什么组件?大组件,还是小组件?

后续开发 Function Component 有什么启发?

  • 内部最好不要有 CPU 密集型计算,可以用 useMemo 进行缓存

对于 JSX 有没有新的认识?

useEffect 和 useLayoutEffect 区别?

Ref 的认知?React 会何时调用 Ref Function?

什么时候可以拿到最新的 DOM 对象?

====

多次 setState 如何合并?

什么是 bailout?什么情况下 bailout?

什么是 eagerState

React 18 将怎么进行中断和恢复?Fiber 深层次工作原理?

from creamidea.github.com.

creamidea avatar creamidea commented on June 24, 2024
// 验证更新层次
import { memo, useMemo, useState } from "react";

function Title() {
  console.log("## render Title");
  return 'title'
}

function Layout() {
  console.log("## render Layout");
  return <Title />
}

function Email() {
  console.log('## render Email')
  return 'email'
}

function Footer({ children }) {
  console.log('## render Footer')
  return children
}

const MemoLayout = memo(Layout)

export function App() {
  console.log('## render App')
  const [state, setState] = useState(0);

  const memoFooter = useMemo(() => {
    return <Footer>
      <Email />
    </Footer>
  }, [])

  // 正常更新,会造成从 App 开始往下所有组件进入 render 阶段
  // 原因:beginWork 阶段 oldProps !== newProps 成立
  // 为啥成立?因为 App render 之后,产出的是新 Fiber 使用的 pendingProps 是新的,区别于 memoizedProps。于是 oldProps !== newProps
  // 优化手段:
  // 1. 使用 memo,比如 memo(Layout)
  // 2. 使用 useMemo 返回组件,比如 useMemo(Footer)
  return <div>
    <button onClick={() => setState(state + 1)}>Click</button>
    <Layout />
    <Footer>
      <Email />
    </Footer>
    <MemoLayout />
    {memoFooter}
  </div>
}

from creamidea.github.com.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.