Git Product home page Git Product logo

react-illustration-series's Introduction

图解 React 源码系列

react源码, 基于[email protected](尽可能跟随 react 版本的升级, 持续更新). 用大量配图的方式, 致力于将react原理表述清楚.

使用指南

  1. 本系列以 react 核心包结构和运行机制为主线索进行展开. 包括react 宏观结构, react 工作循环, react 启动模式, react fiber原理, react hook原理, react 合成事件等核心内容.
  2. 开源作品需要社区的净化和参与, 如有表述不清晰或表述错误, 欢迎issue 勘误. 如果对你有帮助, 请不吝 star.
  3. 本系列最初写作于 2020 年 6 月(当时稳定版本是 v16.13.1), 随着 react 官方的升级, 本 repo 会将主要版本的文章保存在以版本号命名的分支中.
  4. 当下前端技术圈总体比较浮躁, 各技术平台充斥着不少"标题党". 真正对于技术本身, 不能急于求成, 需要静下心来修炼.
  5. 本系列不是面经, 但会列举一些面试题来加深对 react 理解.
  6. 本系列所有内容皆为原创, 如需转载, 请注明出处.

适用读者

  1. react,react-dom开发 web 应用有实践经验.
  2. 期望深入理解react内在作用原理.

版本跟踪

本系列暂时只跟踪稳定版本的变动. react仓库代码改动比较频繁, 在写作过程中, 如果伴随小版本的发布, 文章中的源码链接会以写作当天的最新小版本为基准.

  • [email protected]作为主版本升级, 相较于 16.x 版本, 在使用层面基本维持不变, 在源码层面需要关注的重大的变动如下

    重大变动 所属板块 官方解释
    重构Fiber.expirationTime并引入Fiber.lanes react-reconciler Initial Lanes implementation #18796
    事件代理节点从 document 变成 rootNode, 取消合成事件的缓存池等 legacy-events(被移除), react-dom/events changes-to-event-delegation
  • [email protected]相较于主版本v17.0.0做了一个点的优化, 改动了 1 个文件, 修复 ie11 兼容问题, 同时提升 v8 内部的执行性能.

主要内容

基本概念

运行核心

数据管理

交互

高频算法

历史版本

react-illustration-series's People

Contributors

7kms avatar afterwind-io avatar babycannotsay avatar chesterchenn avatar dependabot[bot] avatar fengma1992 avatar fennghuang avatar grapedge avatar hamburgerdog avatar holybasil avatar imgbotapp avatar jacty avatar jaluik avatar jgchenu avatar kkaaddff avatar li-jia-nan avatar mzvast avatar programmerleague avatar s749312025 avatar sabertazimi avatar shabbyaaa avatar shiqimei avatar soulike avatar superhuangxu avatar tangliang1 avatar thomas-void0 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-illustration-series's Issues

链表操作的图是不是画错了

image 正确的画法应该是: image

源码和注释:

const sharedQueue: SharedQueue<State> = (updateQueue: any).shared;
  const pending = sharedQueue.pending;
  if (pending === null) { // 若链表中没有元素,则创建单向环状链表,next指向它自己
     update.next = update;
   } else {
     // 有元素,现有队列(pending)指向的是链表的尾部update,
     // pending.next就是头部update,新update会放到现有队列的最后并首尾相连
     // 将新队列的尾部(新插入的update)的next指向队列的首部,实现首位相连
     update.next = pending.next; 
    // 现有队列的最后一个元素的next指向新来的update,实现把新update接到现有队列上
     pending.next = update;
   } 
  // 现有队列的指针总是指向最后一个update,可以通过最后一个寻找出整条链表
  sharedQueue.pending = update;

原理解析的一些误点?

image
这里说ReactDOM(Blocking)Root对象上暴露有render和unmount方法,但是我在源码上看了下,在Legacy模式下是Blocking实例是没有这两个方法的,只有Blocking和Concurrent模式下才会有这两个方法,不知道我说得对不对。

fiber 初次构造中 performUnitOfWork 首次调用前的内存状态

在 fibertree-create.md 的 “过程图解” 小节中对于 performUnitOfWork 第一次调用(只执行 beginWork ) 的描述如下:

执行前: workInProgress指针指向HostRootFiber.alternate对象, 此时current = workInProgress.alternate指向fiberRoot.current是非空的(初次构造, 只在根节点时, current非空).

在执行前 FiberRoot.current 指向的 HostRootFiber 到底是不是为 null?

有的方法会根据 current === null 来判断是否为初次渲染,但是如果这个值为 null,怎么会有 alternate 属性?

先提前感谢大佬解答

hook-state 一节中 baseQueue拼接后的链表顺序好像有误

hook-state 一节中 baseQueue拼接后的链表顺序好像有误,和给到的demo中的dispatch顺序不符
dispatch
baseQueue拼接后

我理解应该为1、3、2
132

具体代码为:

 // 2. 链表拼接: 将 hook.queue.pending 拼接到 current.baseQueue
  const pendingQueue = queue.pending;
  if (pendingQueue !== null) {
    if (baseQueue !== null) {
      const baseFirst = baseQueue.next; // 假设为空 baseQueue.next则指向自己
      const pendingFirst = pendingQueue.next; // pendingQueue 为2 ,pendingQueue.next 则为1
      baseQueue.next = pendingFirst; // baseQueue 指向 1
      pendingQueue.next = baseFirst; // pendingQueue(2) 指向 baseQueue
     // 所以最后是 baseQueue => 1 => 3 => 2( 2指向baseQueue )
    }
    current.baseQueue = baseQueue = pendingQueue;
    queue.pending = null;
  }

fiber树构造(对比更新) -> 过程图解 -> performUnitOfWork第 4 次调用(执行beginWork和completeUnitOfWork)

【beginWork执行过程: 调用updateHostComponent】这里的逻辑是不是错误的呢?
根据上文的逻辑,这里current!==null,应该对比优先级判断当前fiber节点不需要更新
接着调用bailoutOnAlreadyFinishedWork函数,继续判断子节点是否需要更新
!includesSomeLane(renderLane, workInProgress.childLanes)返回true,子节点不需要更新,返回null
进入completeUnitOfWork函数

executionContext 何时为空?

文章中提到executionContext执行栈为空的时候,会取消 schedule 调度, 主动刷新回调队列flushSyncCallbackQueue()

那 executionContext 都在什么情况下为空呢?

fiber树构造阶段的问题

performUnitOfWork第 3 次调用说当前节点fiber.lanes处于渲染优先级范围内,调试了一下发现并不在,发生更新的原因oldProps !== newProps

关于是否执行调度未解释清楚

这个地方关于调度的解释并不明确,源码中是在 legacy或blocking模式下并且执行栈为空才会取消调度,但是这里却解释 legacy 下的任何更新都不会经过调度
image

Can we port this to English in a fork

Just wanted to know if it's fine to fork and create an English variant for this document. Just want to extend some help to the larger community that might not be able to have access to it. If there is an English variant to it would help as well.

completeUnitOfWork 中的部分注释有歧义

感觉这两个地方的注释是有歧义的。图二应该是相邻的下一个兄弟节点。图一的其他子节指的是父节点的其他子节点?
按理来说每次回溯到父节点,都会从左向右遍历兄弟节点,在有兄弟节点的时候都会 return 出去,然后进行外层的 while 。感觉一般情况下图一的代码好像不会被执行。
大佬能否解答下图一在什么情况下才会使 next !== null

image

image

ReactElement的构造过程实际上也是reconciler调和过程?

https://github.com/7kms/react-illustration-series/blob/v17.0.1/docs/algorithm/dfs.md#react-%E5%BD%93%E4%B8%AD%E7%9A%84%E4%BD%BF%E7%94%A8%E5%9C%BA%E6%99%AF

ReactElement不能算是严格的树结构, 为了方便表述, 后文都称之为树.

“在react-reconciler包中, ReactElement的构造过程实际上也是reconciler调和过程. 与fiber树的构造是相互交替, 逐级进行的(在fiber 树构建章节中详细解读, 本节只介绍深度优先遍历的使用场景).”
这一节的描述中说ReactElement的构造是与fiber树的构造相互交替的,但ReactElement是把babel解析jsx得到的js对象通过调用React.createElement生成的。这里应该是先生成全部的ReactElement?再按照深度遍历去生成对应的fiber吧

关于 ‘React 算法之调和算法’ 的 ‘reconcileChildrenArray’部分

React 算法之调和算法’ 的 ‘reconcileChildrenArray’部分,对于第二次循环的解释(第二张图下面),我有一个小疑问,

生成的 fiber 节点fiber(E), fiber(C)可以复用. 其中fiber(C)节点发生了位移(打上Placement标记)
  1. 其中fiber(E)为什么可以复用?老序列中fiber(E)节点的key是 key=d , 而新节点 key=e,key不一样,作者是笔误了吗?
  2. fiber(E)可以复用,但为什么没有位移?老序列中fiber(E)在第5个位置,而新的ReactELement序列中E在第3个位置,明显位置不一样,为什么只有fiber(C)位移了?fiber(E)不应该也位移了吗?

期待作者有空的话 回复一下,非常感谢

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.