fiber大致原理

61 阅读2分钟

个人学习理解与见解

1.先针对hooks说一下看法

先看看例子:

function App() {
  const [num, updateNum] = useState(0);
  
  function increment() {
    setTimeout(() => {
      updateNum(num + 1);
    }, 1000);
  }
  
  return <p onClick={increment}>{num}</p>;
}

//另一个例子:
function App() {
  const [num, updateNum] = useState(0);
  
  function increment() {
    setTimeout(() => {
      updateNum(num=>num + 1);
    }, 1000);
  }
  
  return <p onClick={increment}>{num}</p>;
}

这个例子想必大家都看过无数次, 答案也是显而易见, 无论怎么点击结果都是1,

就如命运一般, 注定的事情, 有时我们无论怎么努力都无力回天

所以头铁的我如何逆天改命, 只有了解其中原理才可打破桎梏

来看看原理具体怎么回事吧

相信大家也基本有个初步看法, 每次点击的时候只能拿到最初的num: 0 具体详见: 下一篇useState原理


针对组件: 大家都知道 react Fiber(虚拟dom)

在react15之前是通过递归的方式创建虚拟dom, 如果组件层级很深, 势必会导致渲染时间很长, 导致卡顿

那为了解决这个问题怎么办呢, 那必然就是可中断式更新,所以react 16 用上了全新的可中断式更新架构fiber

我们看看大致定义(其实标签的定义):

function FiberNode(
  tag: WorkTag,
  pendingProps: mixed,
  key: null | string,
  mode: TypeOfMode,
) {
  // 作为静态数据结构的属性
  this.tag = tag;
  this.key = key;
  this.elementType = null;
  this.type = null;
  this.stateNode = null;

  // 用于连接其他Fiber节点形成Fiber树
  this.return = null;
  this.child = null;
  this.sibling = null;
  this.index = 0;

  this.ref = null;

  // 作为动态的工作单元的属性
  this.pendingProps = pendingProps;
  this.memoizedProps = null;
  this.updateQueue = null;
  this.memoizedState = null;
  this.dependencies = null;

  this.mode = mode;

  this.effectTag = NoEffect;
  this.nextEffect = null;

  this.firstEffect = null;
  this.lastEffect = null;

  // 调度优先级相关
  this.lanes = NoLanes;
  this.childLanes = NoLanes;

  // 指向该fiber在另一次更新时对应的fiber
  this.alternate = null;
}

: 链表

旧:

新:

疑问: 为什么这样设计呢?

1.之前老架构是深度遍历的形式, 中断无法找回

2.新架构虽然也想一棵树实际更是一个链表, 可中断操作的关键所在