From 4a820136f9d6dc18c213f4ff4b10fd924dbdc801 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=88=B4=E9=B9=8F=E9=B9=8F?= <16602124116@163.com> Date: Sun, 27 Nov 2022 19:57:04 +0800 Subject: [PATCH] commit --- .../src/client/ReactDOMComponentTree.ts | 2 +- .../src/event/plugins/SimpleEventPlugin.ts | 6 +-- .../src/ReactFiberConcurrentUpdates.ts | 47 +++++++++++++++++++ .../react-reconciler/src/ReactFiberHooks.ts | 20 +++++--- .../src/ReactFiberWorkLoop.ts | 8 +++- 5 files changed, 72 insertions(+), 11 deletions(-) diff --git a/packages/react-dom-bindings/src/client/ReactDOMComponentTree.ts b/packages/react-dom-bindings/src/client/ReactDOMComponentTree.ts index 0c74718..ffefdae 100644 --- a/packages/react-dom-bindings/src/client/ReactDOMComponentTree.ts +++ b/packages/react-dom-bindings/src/client/ReactDOMComponentTree.ts @@ -12,7 +12,7 @@ const internalPropsKey = `__reactProps$` + randomKey export function getClosestInstanceFromNode(targetNode: any) { const targetInst = targetNode[internalInstanceKey] - return targetInst + return targetInst || null } export function updateFiberProps(node: any, props: any) { diff --git a/packages/react-dom-bindings/src/event/plugins/SimpleEventPlugin.ts b/packages/react-dom-bindings/src/event/plugins/SimpleEventPlugin.ts index b3ef548..5e8ca90 100644 --- a/packages/react-dom-bindings/src/event/plugins/SimpleEventPlugin.ts +++ b/packages/react-dom-bindings/src/event/plugins/SimpleEventPlugin.ts @@ -1,7 +1,7 @@ import { registerSimpleEvents, topLevelEventsToReactNames } from '../DOMEventProperties' import { accumulateSinglePhaseListeners } from '../DOMPluginEventSystem' import { IS_CAPTURE_PHASE } from '../EventSystemFlags' -import {SyntheticMouseEvent} from '../SyntheticEvent' +import { SyntheticMouseEvent } from '../SyntheticEvent' function extractEvents( dispatchQueue: any, @@ -16,10 +16,10 @@ function extractEvents( const reactName = topLevelEventsToReactNames.get(domEventName) const listeners = accumulateSinglePhaseListeners(targetInst, reactName, nativeEvent.type, isCapturePhase) - let SyntheticEventCtor // 合成事件的构造函数 + let SyntheticEventCtor: any // 合成事件的构造函数 switch (domEventName) { - case 'click': + case 'click': SyntheticEventCtor = SyntheticMouseEvent break default: diff --git a/packages/react-reconciler/src/ReactFiberConcurrentUpdates.ts b/packages/react-reconciler/src/ReactFiberConcurrentUpdates.ts index 7e411e4..a5fa5e2 100644 --- a/packages/react-reconciler/src/ReactFiberConcurrentUpdates.ts +++ b/packages/react-reconciler/src/ReactFiberConcurrentUpdates.ts @@ -1,5 +1,8 @@ import { HostRoot } from './ReactWorkTags' +const concurrentQueue:any = [] +let concurrentQueuesIndex = 0 + export function markUpdateLaneFromFiberToRoot(sourceFiber: any) { let node = sourceFiber let parent = sourceFiber.return @@ -12,3 +15,47 @@ export function markUpdateLaneFromFiberToRoot(sourceFiber: any) { } return null } + +export function enqueueConcurrentHookUpdate(fiber:any, queue:any, update:any){ + enqueueUpdate(fiber,queue,update) + return getRootForUpdateFiber(fiber) +} + +function getRootForUpdateFiber(sourceFiber:any){ + let node = sourceFiber + let parent = node.return + while (parent !== null) { + node = parent + parent = node.return + } + + return node.tag === HostRoot ? node.stateNode : null +} + +//把更新先缓存到数组里面 +function enqueueUpdate(fiber:any, queue:any, update:any) { + concurrentQueue[concurrentQueuesIndex++] = fiber + concurrentQueue[concurrentQueuesIndex++] = queue + concurrentQueue[concurrentQueuesIndex++] = update +} + +export function finishQueueingConcurrentUpdates() { + const endIndex = concurrentQueuesIndex + concurrentQueuesIndex = 0 + let i = 0 + while (i < endIndex) { + const fiber = concurrentQueue[i++] + const queue = concurrentQueue[i++] + const update = concurrentQueue[i++] + if(queue !== null && update !== null) { + const pending = queue.pending + if(pending === null) { + update.next = update + }else { + pending.next = pending.next + pending.next = update + } + queue.pending = update + } + } +} \ No newline at end of file diff --git a/packages/react-reconciler/src/ReactFiberHooks.ts b/packages/react-reconciler/src/ReactFiberHooks.ts index a760f8f..491fb85 100644 --- a/packages/react-reconciler/src/ReactFiberHooks.ts +++ b/packages/react-reconciler/src/ReactFiberHooks.ts @@ -1,10 +1,12 @@ import ReactSharedInternals from 'shared/ReactSharedInternals' +import {scheduleUpdateOnFiber} from "./ReactFiberWorkLoop"; +import {enqueueConcurrentHookUpdate} from './ReactFiberConcurrentUpdates' const { ReactCurrentDispatcher } = ReactSharedInternals -let currentlyRenderingFiber = null +let currentlyRenderingFiber:any = null -let workInProgressHook = null +let workInProgressHook:any = null const HooksDispatcherOnMount = { useReducer: mountReducer @@ -13,7 +15,7 @@ const HooksDispatcherOnMount = { function mountReducer(reducer: any, initialArg: any){ const hook = mountWorkInProgressHook() hook.memoizedState = initialArg - const queue = { + const queue:any = { pending: null, dispatch: null } @@ -28,15 +30,21 @@ function mountReducer(reducer: any, initialArg: any){ * @param queue * @param action */ -function dispatchReducerAction(fiber, queue, action){ - console.log(fiber, queue, action) +function dispatchReducerAction(fiber:any, queue:any, action:any){ + const update:any = { + action, + next: null + } + const root = enqueueConcurrentHookUpdate(fiber, queue, update) + scheduleUpdateOnFiber(root) + // console.log(fiber, queue, action) } /** * 挂载构建中的 hook */ function mountWorkInProgressHook() { - const hook = { + const hook:any = { memoizedState:null, queue: null, // 存放本 hook 的更新队列 next: null // 指向下一个 hook diff --git a/packages/react-reconciler/src/ReactFiberWorkLoop.ts b/packages/react-reconciler/src/ReactFiberWorkLoop.ts index 96a0efc..493f14c 100644 --- a/packages/react-reconciler/src/ReactFiberWorkLoop.ts +++ b/packages/react-reconciler/src/ReactFiberWorkLoop.ts @@ -4,14 +4,19 @@ import { beginWork } from './ReactFiberBeginWork' import { completeWork } from './ReactFiberCompleteWork' import { NoFlags, MutationMask } from './ReactFiberFlags' import { commitMutationEffectsOnFiber } from './ReactFiberCommitWork' +import {finishQueueingConcurrentUpdates} from './ReactFiberConcurrentUpdates' let workInProgress: any = null +let workInProgressRoot:any = null + export function scheduleUpdateOnFiber(root: any) { ensureRootIsScheduled(root) } function ensureRootIsScheduled(root: any) { + if(workInProgressRoot) return + workInProgressRoot = root scheduleCallback(performConcurrentWorkOnRoot.bind(null, root)) } @@ -26,6 +31,7 @@ function performConcurrentWorkOnRoot(root: any) { const finishedWork = root.current.alternate root.finishedWork = finishedWork commitRoot(root) + workInProgressRoot = null } function commitRoot(root: any) { @@ -41,7 +47,7 @@ function commitRoot(root: any) { function prepareFreshStack(root: any) { workInProgress = createWorkInProgress(root.current, null) - console.log(workInProgress) + finishQueueingConcurrentUpdates() } function renderRootSync(root: any) {