We read every piece of feedback, and take your input very seriously.
To see all available qualifiers, see our documentation.
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
基于 React 18.3.1
示例:
const Foo = () => { const [a, setA] = useState(0); const handleClick = () => { setA(1); setA(2); setA(1); }; return <div onClick={handleClick} >{a}</div> }
首次渲染完毕后,点击触发 handleClick,React 内部调用 dispatchSetState,创建 hook 的 update(每调一次 dispatchSetState,都会新建一个 update,有属性 action,next,action 就是实际业务传入的数据)。
handleClick
dispatchSetState
update
action
next
创建完毕后,进一步调用 enqueueConcurrentHookUpdate(fiber, queue, update, lane),把 update 和 queue 更新到内部全局变量 concurrentQueues 上,会先判断 queue.interleaved 是否已经存在,如果不存在,则当前 update 创建循环链表,并将 update 赋值给 queue.interleaved(queue.interleaved = update;),同时把 queue 推入到 concurrentQueues 数组中。
enqueueConcurrentHookUpdate(fiber, queue, update, lane)
queue
concurrentQueues
queue.interleaved
queue.interleaved = update;
之后,触发新的调度 scheduleUpdateOnFiber(TODO 调度逻辑)
scheduleUpdateOnFiber
在新的渲染开启前,会执行 finishQueueingConcurrentUpdates,将存储 concurrentQueues 里的 queue 数据进行处理,即把 queue.interleaved 里的循环链表迁移到 queue.pending 里,供后续使用。
finishQueueingConcurrentUpdates
queue.pending
重新执行函数组件时,useState 内部指向 updateState,实际调用 updateReducer(basicStateReducer, (initialState: any));,在 updateReducer 内部,调用 updateWorkInProgressHook,更新和获取 workInProgressHook,此时,这个 hook 对应的 queue(hook.queue) 就是先前全部变量 concurrentQueues 更新之后的 queue。也就能正常获取 queue.pending,来计算最新的 state 值,并将新值更新到 hook.memoizedState,hook.baseState,hook.baseQueue 上。
useState
updateState
updateReducer(basicStateReducer, (initialState: any));
updateReducer
updateWorkInProgressHook
workInProgressHook
hook.queue
state
hook.memoizedState
hook.baseState
hook.baseQueue
// dispatchSetState 入参 function dispatchSetState<S, A>( fiber: Fiber, queue: UpdateQueue<S, A>, action: A, // 在业务中调用时,传入的参数,如例子中的 1 ) // update 格式 const update: Update<S, A> = { lane, action, hasEagerState: false, eagerState: null, next: null, }; // enqueueConcurrentHookUpdateAndEagerlyBailout function enqueueConcurrentHookUpdateAndEagerlyBailout<S, A>( fiber: Fiber, queue: HookQueue<S, A>, update: HookUpdate<S, A>, lane: Lane, ): void { const interleaved = queue.interleaved; if (interleaved === null) { // 创建循环队列 update.next = update; // 存到全局变量 concurrentQueues 上 pushConcurrentUpdateQueue(queue); } else { update.next = interleaved.next; interleaved.next = update; } queue.interleaved = update; } // updateState function updateState<S>( initialState: (() => S) | S, ): [S, Dispatch<BasicStateAction<S>>] { return updateReducer(basicStateReducer, (initialState: any)); }
The text was updated successfully, but these errors were encountered:
No branches or pull requests
useState 初始化
useState 更新
示例:
首次渲染完毕后,点击触发
handleClick
,React 内部调用dispatchSetState
,创建 hook 的update
(每调一次dispatchSetState
,都会新建一个update
,有属性action
,next
,action
就是实际业务传入的数据)。创建完毕后,进一步调用
enqueueConcurrentHookUpdate(fiber, queue, update, lane)
,把update
和queue
更新到内部全局变量concurrentQueues
上,会先判断queue.interleaved
是否已经存在,如果不存在,则当前update
创建循环链表,并将update
赋值给queue.interleaved
(queue.interleaved = update;
),同时把queue
推入到concurrentQueues
数组中。之后,触发新的调度
scheduleUpdateOnFiber
(TODO 调度逻辑)在新的渲染开启前,会执行
finishQueueingConcurrentUpdates
,将存储concurrentQueues
里的queue
数据进行处理,即把queue.interleaved
里的循环链表迁移到queue.pending
里,供后续使用。重新执行函数组件时,
useState
内部指向updateState
,实际调用updateReducer(basicStateReducer, (initialState: any));
,在updateReducer
内部,调用updateWorkInProgressHook
,更新和获取workInProgressHook
,此时,这个 hook 对应的queue
(hook.queue
) 就是先前全部变量concurrentQueues
更新之后的queue
。也就能正常获取queue.pending
,来计算最新的state
值,并将新值更新到hook.memoizedState
,hook.baseState
,hook.baseQueue
上。TODO
The text was updated successfully, but these errors were encountered: