Fiber 数据结构是怎样的?

前端精髓

共 2707字,需浏览 6分钟

 ·

2022-01-21 11:53


每个 Virtual DOM 都可以表示为一个 fiber,如下图所示,每个节点都是一个 fiber。一个 fiber包括了 child(第一个子节点)、sibling(兄弟节点)、return(父节点)等属性。


PS:这里需要说明一下,Fiber 是 React 进行重构的核心算法,fiber 是指数据结构中的每一个节点,如下图所示的A1、B1都是一个 fiber。


实现虚拟 DOM 构建 fiber 树。

let A = {  type: 'div',  key: 'A',  props: {    children: [      { type: 'div', key: 'B1', props: { children: []} },      { type: 'div', key: 'B2', props: { children: []} }    ]  }}

let workInProgress;const TAG_ROOT = 'TAG_ROOT' // 根fiberconst TAG_HOST = 'TAG_HOST' // 原生DOM节点
function workLoop () { while(workInProgress) { workInProgress = performaUnitOfWork(workInProgress) }}
let root = document.getElementById('root')// fiber是一个普通的JS对象let rootFiber = { tag: TAG_ROOT, // fiber类型 key: 'ROOT', // 唯一标识 stateNode: root, // fiber对应真实DOM props: { children: [A] // 虚拟DOM成为根fiber唯一的children }}
function performaUnitOfWork(workInProgress) { beginWork(workInProgress) if (workInProgress.child) { return workInProgress.child } while(workInProgress) { if (workInProgress.sibling) { return workInProgress.sibling } workInProgress = workInProgress.return }}// 根据当前fiber和虚拟DOM构建fiber树function beginWork(workInProgress) { console.log('beginWork', workInProgress.key) let nextChildren = workInProgress.props.children return reconcileChildren(workInProgress, nextChildren)}// 根据父fiber和子虚拟DOM,构建当前returnFiber的子fiber树function reconcileChildren(returnFiber, nextChildren) { let previousNewFiber; let firstChildFiber; for (let newIndex = 0; newIndex < nextChildren.length; newIndex++) { let newFiber = createFiber(nextChildren[newIndex]) newFiber.return = returnFiber if (!firstChildFiber) { firstChildFiber = newFiber } else { previousNewFiber.sibling = newFiber } previousNewFiber = newFiber } returnFiber.child = firstChildFiber return firstChildFiber}function createFiber (element) { return { tag: TAG_HOST, type: element.type, key: element.key, props: element.props }}// 当前真正执行的工作单元workInProgress = rootFiberworkLoop()


fiber 节点包括了以下的属性:

(1)type & key

fiber 的 type 和 key 与 React 元素的作用相同。fiber 的 type 描述了它对应的组件,对于复合组件,type 是函数或类组件本身。对于原生标签(div,span等),type 是一个字符串。随着 type 的不同,在 reconciliation 期间使用 key 来确定 fiber 是否可以重新使用。


(2)stateNode

stateNode 保存对组件的类实例,DOM节点或与 fiber 节点关联的其他 React 元素类型的引用。一般来说,可以认为这个属性用于保存与 fiber 相关的本地状态。


(3)child & sibling & return

child 属性指向此节点的第一个子节点(大儿子)。sibling 属性指向此节点的下一个兄弟节点(大儿子指向二儿子、二儿子指向三儿子)。return 属性指向此节点的父节点,即当前节点处理完毕后,应该向谁提交自己的成果。如果 fiber 具有多个子 fiber,则每个子 fiber 的 return fiber 是 parent 。


所有 fiber 节点都通过以下属性:child,sibling 和 return来构成一个 fiber node 的 linked list(后面我们称之为链表)。如下图所示:


浏览 62
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
点赞
评论
收藏
分享

手机扫一扫分享

分享
举报