react的类组件每产生一个更新, 就会创建相应的update, 并追加到该组件对应的fiber上的updateQueue单向链表上, 那么updateQueue的结构是怎样的, 来记录下.

更新


[2019-7-17]

  • Initial release

前言


react每产生一次更新, 都会:

  • 计算expirationTime
  • 创建update
  • 初始化update参数
  • update追加到updateQueue

那么, 问题来了, 这个updateQueue是一种什么结构?

带着问题, 来到源码看一下

分析


enqueueUpdate

react在执行将update追加到updateQueue操作的时候, 会判断当前fiber节点上是否已经具有updateQueue, 如果没有, 会调用createUpdateQueue创建一个新的队列.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export function enqueueUpdate<State>(fiber: Fiber, update: Update<State>) {
const alternate = fiber.alternate;
let queue1;
let queue2;

if (alternate === null) {
// There's only one fiber.
queue1 = fiber.updateQueue;
queue2 = null;
if (queue1 === null) {
// updateQueue不存在, 创建新的
queue1 = fiber.updateQueue = createUpdateQueue(fiber.memoizedState);
}
}
}

createUpdateQueue

上面已经说过了, createUpdateQueue会创建一个新的单向链表状的更新队列

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
export function createUpdateQueue<State>(
// 初始的state
baseState: State
): UpdateQueue<State> {
const queue: UpdateQueue<State> = {
baseState,
firstUpdate: null,
lastUpdate: null,
firstCapturedUpdate: null,
lastCapturedUpdate: null,
firstEffect: null,
lastEffect: null,
firstCapturedEffect: null,
lastCapturedEffect: null,
};

return queue;
}

updateQueue

最后来看一下updateQueue的结构定义:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
export type UpdateQueue<State> = {
// 初始的state
baseState: State,

// 链表中的第一/最后一个update
firstUpdate: Update<State> | null,
lastUpdate: Update<State> | null,

// 链表中的第一/最后一个更新出现错误的update
firstCapturedUpdate: Update<State> | null,
lastCapturedUpdate: Update<State> | null,

// 链表中的第一/最后一个副作用(DOM diff的结果)
firstEffect: Update<State> | null,
lastEffect: Update<State> | null,

firstCapturedEffect: Update<State> | null,
lastCapturedEffect: Update<State> | null,
};