1mikasa1 / react-demo

0 stars 0 forks source link

React18源码-02createRoot中发生了什么 #5

Open 1mikasa1 opened 2 years ago

1mikasa1 commented 2 years ago

/**

1mikasa1 commented 2 years ago

生成一个reactrootFiber createContainer

/**

1mikasa1 commented 2 years ago

createFiberRoot

/**

function createFiberRoot(containerInfo, tag, hydrate, initialChildren, hydrationCallbacks, isStrictMode, concurrentUpdatesByDefaultOverride,identifierPrefix, onRecoverableError, transitionCallbacks) { // 生成一颗fiber树,对同一个元素重复调用render时不会重复生成 var root = new FiberRootNode(containerInfo, tag, hydrate, identifierPrefix, onRecoverableError);

1.生成rootFiber实例 rootFiber是所在组件树的根节点,rootFiber在每次重新渲染的时候会重新构建。 2.在应用中当多次调用ReactDOM.render渲染不同的组件树的时候,它们会拥有不同的rootFiber,但整个应用的根节点只有一个fiberRootNode。fiberRootNode的current会指向当前页面上已渲染内容对应Fiber树,即current Fiber树。 var uninitializedFiber = createHostRootFiber(tag, isStrictMode); root.current = uninitializedFiber; uninitializedFiber.stateNode = root;

{ var _initialState = { element: initialChildren, isDehydrated: hydrate, cache: null, // not enabled yet transitions: null }; uninitializedFiber.memoizedState = _initialState; }

初始化更新队列 initializeUpdateQueue(uninitializedFiber); return root; }

1mikasa1 commented 2 years ago

initializeUpdateQueue

function initializeUpdateQueue(fiber) { var queue = { baseState: fiber.memoizedState, // 当前state状态 firstBaseUpdate: null, // 队列的第一个元素 lastBaseUpdate: null, // 队列的最后一个元素 shared: { pending: null, interleaved: null, lanes: NoLanes }, effects: null }; fiber.updateQueue = queue; }

1mikasa1 commented 2 years ago

在根节点上做事件委托

监听所有浏览器支持的事件 function listenToAllSupportedEvents(rootContainerElement) { 如果没有则进行绑定 if (!rootContainerElement[listeningMarker]) { rootContainerElement[listeningMarker] = true; allNativeEvents.forEach(function (domEventName) { if (domEventName !== 'selectionchange') { if (!nonDelegatedEvents.has(domEventName)) { listenToNativeEvent(domEventName, false, rootContainerElement); } listenToNativeEvent(domEventName, true, rootContainerElement); } }); ... } }

1mikasa1 commented 2 years ago

所有支持的事件做一个优先级分类,并赋予这些事件不同的优先级: function createEventListenerWrapperWithPriority(targetContainer, domEventName, eventSystemFlags) { // 根据不同的事件做优先级分类 var eventPriority = getEventPriority(domEventName); var listenerWrapper; //根据优先级分类,设置事件触发时的优先级,三类事件优先级逐步降低 switch (eventPriority) { // click,blur,focus,submit,tuchStart 等,优先级最高 case DiscreteEventPriority: listenerWrapper = dispatchDiscreteEvent; break; // 连续事件,例如:滚动事件,拖动事件等,连续触发的事件 case ContinuousEventPriority: listenerWrapper = dispatchContinuousEvent; break; // 默认事件 case DefaultEventPriority: default: listenerWrapper = dispatchEvent; break; } return listenerWrapper.bind(null, domEventName, eventSystemFlags, targetContainer); }