更新可以設(shè)置優(yōu)先級(jí),在處理更新的時(shí)候可以指定渲染優(yōu)先級(jí)贾虽,高于指定渲染優(yōu)先級(jí)的更新才能渲染埠胖。React中使用lane(車道)表示任務(wù)優(yōu)先級(jí),共有31個(gè)lane攒盈,數(shù)字越小優(yōu)先級(jí)越高,有些lane優(yōu)先級(jí)相同哎榴。
代碼詳情
const NoLanes = 0b00;
const NoLane = 0b00;
const SyncLane = 0b01;
const InputContinuousHydrationLane = 0b10;
function isSubsetOfLanes(set, subset) {
return (set & subset) === subset;
}
function mergeLanes(a, b) {
return a | b;
}
function initializeUpdateQueue(fiber) {
const queue = {
baseState: fiber.memoizedState,
firstBaseUpdate: null,
lastBaseUpdate: null,
shared: {
pending: null,
},
};
fiber.updateQueue = queue;
}
function enqueueUpdate(fiber, update) {
const updateQueue = fiber.updateQueue;
const sharedQueue = updateQueue.shared;
const pending = sharedQueue.pending;
if (pending === null) {
update.next = update;
} else {
update.next = pending.next;
pending.next = update;
}
sharedQueue.pending = update;
}
function processUpdateQueue(fiber, renderLanes) {
const queue = fiber.updateQueue;
let firstBaseUpdate = queue.firstBaseUpdate;
let lastBaseUpdate = queue.lastBaseUpdate;
const pendingQueue = queue.shared.pending;
if (pendingQueue !== null) {
queue.shared.pending = null;
const lastPendingUpdate = pendingQueue;
const firstPendingUpdate = lastPendingUpdate.next;
lastPendingUpdate.next = null;
if (lastBaseUpdate === null) {
firstBaseUpdate = firstPendingUpdate;
} else {
lastBaseUpdate.next = firstPendingUpdate;
}
lastBaseUpdate = lastPendingUpdate;
}
if (firstBaseUpdate !== null) {
let newState = queue.baseState;
let newLanes = NoLanes;
let newBaseState = null;
let newFirstBaseUpdate = null;
let newLastBaseUpdate = null;
let update = firstBaseUpdate;
do {
const updateLane = update.lane;
if (updateLane > renderLanes) {
const clone = {
id: update.id,
lane: updateLane,
payload: update.payload,
};
if (newLastBaseUpdate === null) {
newFirstBaseUpdate = newLastBaseUpdate = clone;
newBaseState = newState;
} else {
newLastBaseUpdate = newLastBaseUpdate.next = clone;
}
newLanes = mergeLanes(newLanes, updateLane);
} else {
if (newLastBaseUpdate !== null) {
const clone = {
id: update.id,
lane: NoLane,
payload: update.payload,
};
newLastBaseUpdate = newLastBaseUpdate.next = clone;
}
newState = getStateFromUpdate(update, newState);
}
update = update.next;
} while (update);
if (!newLastBaseUpdate) {
newBaseState = newState;
}
queue.baseState = newBaseState;
queue.firstBaseUpdate = newFirstBaseUpdate;
queue.lastBaseUpdate = newLastBaseUpdate;
fiber.lanes = newLanes;
fiber.memoizedState = newState;
}
}
function getStateFromUpdate(update, prevState) {
return update.payload(prevState);
}
let fiber = {
memoizedState: "",
};
initializeUpdateQueue(fiber);
let updateA = {
id: "A",
payload: (state) => state + "A",
lane: SyncLane,
};
enqueueUpdate(fiber, updateA);
let updateB = {
id: "B",
payload: (state) => state + "B",
lane: InputContinuousHydrationLane,
};
enqueueUpdate(fiber, updateB);
let updateC = {
id: "C",
payload: (state) => state + "C",
lane: SyncLane,
};
enqueueUpdate(fiber, updateC);
let updateD = {
id: "D",
payload: (state) => state + "D",
lane: SyncLane,
};
enqueueUpdate(fiber, updateD);
processUpdateQueue(fiber, SyncLane);
console.log(fiber.memoizedState);
console.log("updateQueue", printUpdateQueue(fiber.updateQueue));
let updateE = {
id: "E",
payload: (state) => state + "E",
lane: InputContinuousHydrationLane,
};
enqueueUpdate(fiber, updateE);
let updateF = {
id: "F",
payload: (state) => state + "F",
lane: SyncLane,
};
enqueueUpdate(fiber, updateF);
processUpdateQueue(fiber, InputContinuousHydrationLane);
console.log(fiber.memoizedState);
console.log("updateQueue", printUpdateQueue(fiber.updateQueue));
function printUpdateQueue(updateQueue) {
const { baseState, firstBaseUpdate } = updateQueue;
let desc = baseState + "#";
let update = firstBaseUpdate;
while (update) {
desc += update.id + "=>";
update = update.next;
}
desc += "null";
return desc;
}
// 渲染結(jié)果
// ACD
// updateQueue A#B=>C=>D=>null
// ABCDEF
// updateQueue ABCDEF#null