React beginWork

8540 단어 react.js

beginWork


params

  • current: mount 시: rootFiber와 rootWorkInProgrss의current만!==null;기타 current =null
  • workInProgress
  • renderLanes

  • tag에 따라 다른 방법을 실행한다.

  • mountIndeterminateComponent: 함수인지 클래스인지 확실하지 않습니다
  • updateFunctionComponent:
  • renderWithHooks
  • reconcileChildren

  • updateClassComponent:
  • 코드는 다음과 같다
  • //  
    if (instance === null) {
      //   current  
      if (current !== null) {
        current.alternate = null;
        workInProgress.alternate = null;
        workInProgress.flags |= Placement;
      }
      /**
       * 1.  ,  state   memoizedState
       * 2.   adoptClassInstance
       */
      constructClassInstance(workInProgress, Component, nextProps);
      /**
       * 1. initializeUpdateQueue:   fiber   updateQueue
       * 2. processUpdateQueue:   state  
       */
      mountClassInstance(workInProgress, Component, nextProps, renderLanes);
      shouldUpdate = true;
    } else if (current === null) {
      //  ,  current  
      //   instace  
      shouldUpdate = resumeMountClassInstance(
        workInProgress,
        Component,
        nextProps,
        renderLanes
      );
    } else {
      /**
       * 1. cloneUpdateQueue
       * 2. processUpdateQueue
       */
      shouldUpdate = updateClassInstance(
        current,
        workInProgress,
        Component,
        nextProps,
        renderLanes
      );
    }
  • reconcileChildren

  • updateHostRoot: FiberRoot
  • cloneUpdateQueue
  • processUpdateQueue
  • reconcileChildren


  • 코드

  • initializeUpdateQueue
    function initializeUpdateQueue(fiber) {
      var queue = {
        baseState: fiber.memoizedState,
        firstBaseUpdate: null,
        lastBaseUpdate: null,
        shared: {
          pending: null,
        },
        effects: null,
      };
      fiber.updateQueue = queue;
    }
  • processUpdateQueue
  • state 값을 계산합니다
  • mount: state를 workInProgress에 할당합니다.memoizedState;Queue가 업데이트됩니다.baseState 할당
  • update
  • function processUpdateQueue(workInProgress, props, instance, renderLanes) {
      var queue = workInProgress.updateQueue;
      hasForceUpdate = false;
    
      {
        currentlyProcessingQueue = queue.shared;
      }
    
      var firstBaseUpdate = queue.firstBaseUpdate;
      var lastBaseUpdate = queue.lastBaseUpdate;
      var pendingQueue = queue.shared.pending;
    
      if (pendingQueue !== null) {
        queue.shared.pending = null;
    
        var lastPendingUpdate = pendingQueue;
        var firstPendingUpdate = lastPendingUpdate.next;
        lastPendingUpdate.next = null;
    
        if (lastBaseUpdate === null) {
          firstBaseUpdate = firstPendingUpdate;
        } else {
          lastBaseUpdate.next = firstPendingUpdate;
        }
    
        lastBaseUpdate = lastPendingUpdate;
    
        var current = workInProgress.alternate;
    
        if (current !== null) {
          var currentQueue = current.updateQueue;
          var currentLastBaseUpdate = currentQueue.lastBaseUpdate;
    
          if (currentLastBaseUpdate !== lastBaseUpdate) {
            if (currentLastBaseUpdate === null) {
              currentQueue.firstBaseUpdate = firstPendingUpdate;
            } else {
              currentLastBaseUpdate.next = firstPendingUpdate;
            }
    
            currentQueue.lastBaseUpdate = lastPendingUpdate;
          }
        }
      }
    
      if (firstBaseUpdate !== null) {
        var newState = queue.baseState;
    
        var newLanes = NoLanes;
        var newBaseState = null;
        var newFirstBaseUpdate = null;
        var newLastBaseUpdate = null;
        var update = firstBaseUpdate;
    
        do {
          var updateLane = update.lane;
          var updateEventTime = update.eventTime;
    
          if (!isSubsetOfLanes(renderLanes, updateLane)) {
            var clone = {
              eventTime: updateEventTime,
              lane: updateLane,
              tag: update.tag,
              payload: update.payload,
              callback: update.callback,
              next: null,
            };
    
            if (newLastBaseUpdate === null) {
              newFirstBaseUpdate = newLastBaseUpdate = clone;
              newBaseState = newState;
            } else {
              newLastBaseUpdate = newLastBaseUpdate.next = clone;
            }
    
            newLanes = mergeLanes(newLanes, updateLane);
          } else {
            if (newLastBaseUpdate !== null) {
              var _clone = {
                eventTime: updateEventTime,
                lane: NoLane,
                tag: update.tag,
                payload: update.payload,
                callback: update.callback,
                next: null,
              };
              newLastBaseUpdate = newLastBaseUpdate.next = _clone;
            }
    
            newState = getStateFromUpdate(
              workInProgress,
              queue,
              update,
              newState,
              props,
              instance
            );
            var callback = update.callback;
    
            if (callback !== null) {
              workInProgress.flags |= Callback;
              var effects = queue.effects;
    
              if (effects === null) {
                queue.effects = [update];
              } else {
                effects.push(update);
              }
            }
          }
    
          update = update.next;
    
          if (update === null) {
            pendingQueue = queue.shared.pending;
    
            if (pendingQueue === null) {
              break;
            } else {
              var _lastPendingUpdate = pendingQueue;
    
              var _firstPendingUpdate = _lastPendingUpdate.next;
              _lastPendingUpdate.next = null;
              update = _firstPendingUpdate;
              queue.lastBaseUpdate = _lastPendingUpdate;
              queue.shared.pending = null;
            }
          }
        } while (true);
    
        if (newLastBaseUpdate === null) {
          newBaseState = newState;
        }
    
        queue.baseState = newBaseState;
        queue.firstBaseUpdate = newFirstBaseUpdate;
        queue.lastBaseUpdate = newLastBaseUpdate;
    
        markSkippedUpdateLanes(newLanes);
        workInProgress.lanes = newLanes;
        workInProgress.memoizedState = newState;
      }
    
      {
        currentlyProcessingQueue = null;
      }
    }
  • adoptClassInstance
  • instance.update: this.setState 사용
  • workInProgress.stateNode = instance;
  • function adoptClassInstance(workInProgress, instance) {
      instance.updater = classComponentUpdater;
      workInProgress.stateNode = instance;
    
      set(instance, workInProgress);
    
      {
        instance._reactInternalInstance = fakeInternalInstance;
      }
    }
  • classComponentUpdater 객체
    var classComponentUpdater = {
      isMounted: isMounted,
      enqueueSetState: function (inst, payload, callback) {
        var fiber = get(inst);
        var eventTime = requestEventTime();
        var lane = requestUpdateLane(fiber);
        var update = createUpdate(eventTime, lane);
        update.payload = payload;
    
        if (callback !== undefined && callback !== null) {
          {
            warnOnInvalidCallback(callback, "setState");
          }
    
          update.callback = callback;
        }
    
        enqueueUpdate(fiber, update);
        scheduleUpdateOnFiber(fiber, lane, eventTime);
      },
      enqueueReplaceState: function (inst, payload, callback) {
        var fiber = get(inst);
        var eventTime = requestEventTime();
        var lane = requestUpdateLane(fiber);
        var update = createUpdate(eventTime, lane);
        update.tag = ReplaceState;
        update.payload = payload;
    
        if (callback !== undefined && callback !== null) {
          {
            warnOnInvalidCallback(callback, "replaceState");
          }
    
          update.callback = callback;
        }
    
        enqueueUpdate(fiber, update);
        scheduleUpdateOnFiber(fiber, lane, eventTime);
      },
      enqueueForceUpdate: function (inst, callback) {
        var fiber = get(inst);
        var eventTime = requestEventTime();
        var lane = requestUpdateLane(fiber);
        var update = createUpdate(eventTime, lane);
        update.tag = ForceUpdate;
    
        if (callback !== undefined && callback !== null) {
          {
            warnOnInvalidCallback(callback, "forceUpdate");
          }
    
          update.callback = callback;
        }
    
        enqueueUpdate(fiber, update);
        scheduleUpdateOnFiber(fiber, lane, eventTime);
      },
    };
  • renderWithHooks
  • currentlyRenderingFiber$1 = workInProgress;
  • 함수 구성 요소 실행:Component(props,secondArg);함수 구성 요소의hooks도 실행됩니다.훅스를 Fiber에 마운트합니다.memoizedState
  • function mountWorkInProgressHook() {
      var hook = {
        memoizedState: null,
        baseState: null,
        baseQueue: null,
        queue: null,
        next: null,
      };
    
      if (workInProgressHook === null) {
        currentlyRenderingFiber$1.memoizedState = workInProgressHook = hook;
      } else {
        workInProgressHook = workInProgressHook.next = hook;
      }
    
      return workInProgressHook;
    }

    좋은 웹페이지 즐겨찾기