第四章 初始化UpdateQueue、添加update(React18源码解析四)

158 阅读2分钟

第一章 JSX(React18源码解析一)
第二章 实现Virtual DOM(React18源码解析二)
第三章 根节点关联根Fiber(React18源码解析三)
第四章 初始化UpdateQueue、添加update(React18源码解析四)
第五章 实现时间切片函数和拷贝Fiber(React18源码解析五)
第六章 构建FiberTree(React18源码解析六)
第七章 commit(React18源码解析七)
第八章 React中的事件(React18源码解析八)
第九章 useReducer、useState(React18源码解析九)
第十章 React的dom diff(React18源码解析十)
第十一章 React的Effect(React18源码解析十一)
第十二章 React的同步、并发渲染(React18源码解析十二)
第十三章 React高优打断低优、饥饿问题(React18源码解析十三)

一.初始化UpdateQueue

//react-18.0.0/packages/react-reconciler/src/ReactUpdateQueue.old.js
//createFiberRoot中调用initializeUpdateQueue(uninitializedFiber)初始化UpdateQueue,及在RootFiber创建阶段初始化UpdateQueue

export function initializeUpdateQueue{
  const queue = {
    baseState: fiber.memoizedState,
    firstBaseUpdate: null,
    lastBaseUpdate: null,
    shared: {
      pending: null,
      interleaved: null,
      lanes: NoLanes,
    },
    effects: null,
  };
  fiber.updateQueue = queue;
}

二.ReactDOMRoot.prototype.render

//react-18.0.0/packages/react-dom/src/client/ReactDOMRoot.js
//在ReactDOMRoot原型上添加render,RootNode调用render开始渲染,内部调用updateContainer
ReactDOMHydrationRoot.prototype.render = ReactDOMRoot.prototype.render = function(
  children,
) {
  const root = this._internalRoot;
  updateContainer(children, root, null, null);
};

三.调用enqueueUpdate把update添加到fiber上

//react-18.0.0/packages/react-reconciler/src/ReactFiberReconciler.old.js
export function updateContainer(
  element,
  container,
  parentComponent,
  callback,
) {

  const current = container.current;
  //eventTime获取当前时间、lane通道,为后文讲述的update优先级服务
  const eventTime = requestEventTime();
  const lane = requestUpdateLane(current);

  //创建一个更新
  const update = createUpdate(eventTime, lane);
  update.payload = {element};

  //把update添加到fiber.updateQueue
  enqueueUpdate(current, update, lane);

  return lane;
}

四.createUpdate、enqueueUpdate具体实现

//react-18.0.0/packages/react-reconciler/src/ReactUpdateQueue.old.js
export function createUpdate(eventTime,lane){
  const update = {
    eventTime,
    lane,

    tag: UpdateState,
    payload: null,
    callback: null,

    next: null,
  };
  return update;
}

//react-18.0.0/packages/react-reconciler/src/ReactUpdateQueue.old.js
export function enqueueUpdate(
  fiber,
  update,
  lane,
) {
  const updateQueue = fiber.updateQueue;
  if (updateQueue === null) {
    return;
  }
  const sharedQueue= updateQueue.shared;
  //updates构建循环链表,用updateQueue.shared.interleaved或updateQueue.shared.pending指向最后一个update
  if (isInterleavedUpdate(fiber, lane)) {
    const interleaved = sharedQueue.interleaved;
    if (interleaved === null) {
      update.next = update;
      pushInterleavedQueue(sharedQueue);
    } else {
      update.next = interleaved.next;
      interleaved.next = update;
    }
    sharedQueue.interleaved = update;
  } else {
    const pending = sharedQueue.pending;
    if (pending === null) {
      update.next = update;
    } else {
      update.next = pending.next;
      pending.next = update;
    }
    sharedQueue.pending = update;
  }
}

备注:

 本文为清晰展现出本文核心逻辑把粘贴的源码中参数校验、typescript类型、不相关逻辑等已删除