useReducer更新源码实现
packages/react-reconciler/src/ReactFiberHooks.js
js
import { scheduleUpdateOnFiber } from "./ReactFiberWorkLoop";
import { enqueueConcurrentHookUpdate } from './ReactFiberConcurrentUpdates';
function dispatchReducerAction(fiber, queue, action) {
const update = {
action,
next: null
}
const root = enqueueConcurrentHookUpdate(fiber, queue, update);
scheduleUpdateOnFiber(root);
}
export function renderWithHooks(current, workInProgress, Component, props) {
currentlyRenderingFiber = workInProgress; // 设置当前正在渲染的fiber节点
if (current !== null && current.memoizedState !== null) {
ReactCurrentDispatcher.current = HooksDispatcherOnUpdate;
} else {
ReactCurrentDispatcher.current = HooksDispatcherOnMount;
}
const children = Component(props); // 通过组件和props渲染子节点
currentlyRenderingFiber = null;
workInProgressHook = null;
currentHook = null;
return children; // 返回子节点
}packages/react-reconciler/src/ReactFiberConcurrentUpdates.js
js
const concurrentQueue = [];
let concurrentQueuesIndex = 0;
function enqueueUpdate(fiber, queue, update) {
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 {
update.next = pending.next;
pending.next = update;
}
queue.pending = update;
}
}
}packages/react-reconciler/src/ReactFiberWorkLoop.js
js
import { finishQueueingConcurrentUpdates } from './ReactFiberConcurrentUpdates';
function prepareFreshStack(root) {
workInProgress = createWorkInProgress(root.current, null);
finishQueueingConcurrentUpdates()
}