Fiber 数据结构是怎样的?

3d27d15fe48a1a4f9b64276783a8bbbd.png

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

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

5c8325df4fdab01655a77e32668420ba.png

实现虚拟 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' // 根fiber
const 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 = rootFiber
workLoop()

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(后面我们称之为链表)。如下图所示:

9ea754b53df65ef8389ec2e9de3d58ae.png

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值