Skip to content

Commit 8ef9604

Browse files
committed
feat(reaconciler): 新增 更新阶段源码注释
1 parent 0908134 commit 8ef9604

File tree

7 files changed

+2473
-1645
lines changed

7 files changed

+2473
-1645
lines changed

Diff for: docs/img/render.dio

+2,258-1,637
Large diffs are not rendered by default.

Diff for: docs/img/update.dio

+159
Large diffs are not rendered by default.

Diff for: src/App.js

+6-3
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,15 @@ function App() {
2323

2424
useEffect(() => {
2525
console.log('useEffect被执行');
26-
27-
console.log("%c'useEffect被执行 %c", "color:green",)
26+
27+
console.log("%c'useEffect被执行 %c", "color:green",)
2828
return () => {
2929
console.log('useEffect 卸载函数被执行');
3030
}
3131
}, [])
3232

3333
const [flag, setFlag] = useState(true)
34+
const [counter, setCounter] = useState(1)
3435

3536
// 事件系统
3637
// return <EventDemo/>
@@ -41,8 +42,10 @@ console.log("%c'useEffect被执行 %c", "color:green",)
4142
return (
4243
<div className="App" onClick={() => {
4344
debugger;
44-
setFlag(!flag)
45+
// setFlag(!flag)
46+
setCounter(counter + 1);
4547
}}>
48+
<h4>counter:{counter}</h4>
4649
{
4750
flag
4851
? (

Diff for: src/react/v17.0.2/react-reconciler/src/ReactFiberHooks.old.js

+27-3
Original file line numberDiff line numberDiff line change
@@ -1927,6 +1927,15 @@ function dispatchAction<S, A>(
19271927
next: (null: any),
19281928
};
19291929

1930+
// const queue = {
1931+
// dispatch: ƒ (),
1932+
// interleaved: null,
1933+
// lanes: 0,
1934+
// lastRenderedReducer: ƒ basicStateReducer(state, action), // 更新的方法
1935+
// lastRenderedState: 1, // 上一次的值
1936+
// pending: {lane: 1, action: 2, eagerReducer: null, eagerState: null, next: {…}},
1937+
// }
1938+
19301939
const alternate = fiber.alternate;
19311940
if (
19321941
fiber === currentlyRenderingFiber ||
@@ -1955,6 +1964,7 @@ function dispatchAction<S, A>(
19551964
if (interleaved === null) {
19561965
// This is the first update. Create a circular list.
19571966
update.next = update;
1967+
//在当前渲染结束时,此队列的交错更新将被转移到待处理队列。
19581968
// At the end of the current render, this queue's interleaved updates will
19591969
// be transfered to the pending queue.
19601970
pushInterleavedQueue(queue);
@@ -1966,6 +1976,7 @@ function dispatchAction<S, A>(
19661976
} else {
19671977
const pending = queue.pending;
19681978
if (pending === null) {
1979+
// 这是第一次更新。创建一个循环列表。
19691980
// This is the first update. Create a circular list.
19701981
update.next = update;
19711982
} else {
@@ -1979,19 +1990,27 @@ function dispatchAction<S, A>(
19791990
fiber.lanes === NoLanes &&
19801991
(alternate === null || alternate.lanes === NoLanes)
19811992
) {
1993+
1994+
// 队列当前是空的,这意味着我们可以在进入渲染阶段之前急切地计算下一个状态。
1995+
// 如果新状态与当前状态相同,我们或许可以完全退出。
1996+
19821997
// The queue is currently empty, which means we can eagerly compute the
19831998
// next state before entering the render phase. If the new state is the
19841999
// same as the current state, we may be able to bail out entirely.
1985-
const lastRenderedReducer = queue.lastRenderedReducer;
2000+
2001+
// typeof action === 'function' ? action(state) : action;
2002+
const lastRenderedReducer = queue.lastRenderedReducer; // basicStateReducer 内部会判断 是否为函数,如果为函数则会将上一次的值传进去,得到新的 状态
19862003
if (lastRenderedReducer !== null) {
19872004
let prevDispatcher;
19882005
if (__DEV__) {
19892006
prevDispatcher = ReactCurrentDispatcher.current;
19902007
ReactCurrentDispatcher.current = InvalidNestedHooksDispatcherOnUpdateInDEV;
19912008
}
19922009
try {
1993-
const currentState: S = (queue.lastRenderedState: any);
1994-
const eagerState = lastRenderedReducer(currentState, action);
2010+
// 取到上一次的值
2011+
const currentState: S = (queue.lastRenderedState: any);
2012+
// 将上一次的值,传进去,如果这次set 是一个函数,则需要上一次的值,否则直接返回新的值
2013+
const eagerState = lastRenderedReducer(currentState, action);
19952014

19962015
// 将急切计算的状态和用于计算它的reducer保存在更新对象上。
19972016
// 如果 reducer 在我们进入渲染阶段时还没有改变,那么无需再次调用 reducer ,就可以使用 eager 状态。
@@ -2000,9 +2019,14 @@ function dispatchAction<S, A>(
20002019
// it, on the update object. If the reducer hasn't changed by the
20012020
// time we enter the render phase, then the eager state can be used
20022021
// without calling the reducer again.
2022+
2023+
// 记录 reducer 和 state
20032024
update.eagerReducer = lastRenderedReducer;
20042025
update.eagerState = eagerState;
20052026
if (is(eagerState, currentState)) {
2027+
// 快速路径。 我们可以在不安排 React 重新渲染的情况下退出。
2028+
// 如果组件由于不同的原因重新渲染并且到那时 reducer 已经更改,我们仍然可能需要稍后重新调整此更新。
2029+
20062030
// Fast path. We can bail out without scheduling React to re-render.
20072031
// It's still possible that we'll need to rebase this update later,
20082032
// if the component re-renders for a different reason and by that

Diff for: src/react/v17.0.2/react-reconciler/src/ReactFiberSyncTaskQueue.old.js

+5
Original file line numberDiff line numberDiff line change
@@ -21,11 +21,16 @@ let includesLegacySyncCallbacks: boolean = false;
2121
let isFlushingSyncQueue: boolean = false;
2222

2323
export function scheduleSyncCallback(callback: SchedulerCallback) {
24+
25+
// 将此回调推送到内部队列中。 我们将在下一个滴答声中刷新它们,
26+
// 或者如果有东西调用 `flushSyncCallbackQueue` 则更早。
27+
2428
// Push this callback into an internal queue. We'll flush these either in
2529
// the next tick, or earlier if something calls `flushSyncCallbackQueue`.
2630
if (syncQueue === null) {
2731
syncQueue = [callback];
2832
} else {
33+
// 推送到现有队列。 不需要安排回调,因为我们在创建队列时已经安排了一个回调。
2934
// Push onto existing queue. Don't need to schedule a callback because
3035
// we already scheduled one when we created the queue.
3136
syncQueue.push(callback);

Diff for: src/react/v17.0.2/react-reconciler/src/ReactFiberWorkLoop.old.js

+17-1
Original file line numberDiff line numberDiff line change
@@ -675,10 +675,13 @@ export function isInterleavedUpdate(fiber: Fiber, lane: Lane) {
675675
function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
676676
const existingCallbackNode = root.callbackNode;
677677

678+
//检查是否有其他线路被其他工作占用。如果是,将它们标记为过期,
679+
//所以我们知道下一个工作。
678680
// Check if any lanes are being starved by other work. If so, mark them as
679681
// expired so we know to work on those next.
680682
markStarvedLanesAsExpired(root, currentTime);
681683

684+
// 确定接下来的车道,以及它们的优先级。
682685
// Determine the next lanes to work on, and their priority.
683686
const nextLanes = getNextLanes(
684687
root,
@@ -696,10 +699,14 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
696699
}
697700

698701
// We use the highest priority lane to represent the priority of the callback.
702+
// 我们使用最高优先级通道来表示回调的优先级。 newCallbackPriority = 1
699703
const newCallbackPriority = getHighestPriorityLane(nextLanes);
700704

705+
// 检查是否有一个已存在的任务。我们也许可以重新利用它。
701706
// Check if there's an existing task. We may be able to reuse it.
702707
const existingCallbackPriority = root.callbackPriority;
708+
709+
// newCallbackPriority = 1
703710
if (existingCallbackPriority === newCallbackPriority) {
704711
if (__DEV__) {
705712
// If we're going to re-use an existing task, it needs to exist.
@@ -714,20 +721,29 @@ function ensureRootIsScheduled(root: FiberRoot, currentTime: number) {
714721
);
715722
}
716723
}
724+
725+
// 优先级没有改变。我们可以重用现有的任务。出口。
717726
// The priority hasn't changed. We can reuse the existing task. Exit.
718727
return;
719728
}
720729

721730
if (existingCallbackNode != null) {
731+
// 取消现有的回调。我们将在下面安排一个新的。
722732
// Cancel the existing callback. We'll schedule a new one below.
723733
cancelCallback(existingCallbackNode);
724734
}
725735

736+
// 安排一个新的回调
726737
// Schedule a new callback.
727738
let newCallbackNode;
728-
if (newCallbackPriority === SyncLane) {
739+
if (newCallbackPriority === SyncLane) { // 判断是否同步赛道
740+
// 特殊情况: 同步React回调 被安排在一个特殊的内部队列
729741
// Special case: Sync React callbacks are scheduled on a special
730742
// internal queue
743+
/*
744+
export const LegacyRoot = 0; // render
745+
export const ConcurrentRoot = 1; // conCurrentRoot 模式
746+
*/
731747
if (root.tag === LegacyRoot) {
732748
scheduleLegacySyncCallback(performSyncWorkOnRoot.bind(null, root));
733749
} else {

Diff for: src/react/v17.0.2/scheduler/src/forks/SchedulerDOM.js

+1-1
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,7 @@ function forceFrameRate(fps) {
519519
}
520520

521521
const performWorkUntilDeadline = () => {
522-
debugger;
522+
// debugger;
523523
if (scheduledHostCallback !== null) {
524524
const currentTime = getCurrentTime();
525525
// Yield after `yieldInterval` ms, regardless of where we are in the vsync

0 commit comments

Comments
 (0)