16
loading...
This website collects cookies to deliver better user experience
// https://github.com/facebook/react/blob/9212d994ba939f20a04220a61e9776b488381596/packages/react-reconciler/src/ReactFiberLane.new.js
const NoLane: Lane = 0b0000000000000000000000000000000;
const SyncLane: Lane = 0b0000000000000000000000000000001
const TransitionLanes: Lanes = 0b0000000001111111111111111000000;
const IdleLane: Lanes = 0b0100000000000000000000000000000;
const OffscreenLane: Lane = 0b1000000000000000000000000000000;
export function mergeLanes(a: Lanes | Lane, b: Lanes | Lane): Lanes {
return a | b;
}
mergeLanes(
NoLane /*0b0000000000000000000000000000000*/,
OffscreenLane /*0b1000000000000000000000000000000*/
)
// => 0b1000000000000000000000000000000
fiber.lanes = mergeLanes(
fiber.lanes /* NoLane */,
OffscreenLane
)
// => OffscreenLane
isSubsetOfLanes
.export function isSubsetOfLanes(set: Lanes, subset: Lanes) {
return (set & subset) === subset;
}
isSubsetOfLanes(
NonIdleLanes, /*0b0001111111111111111111111111111*/
SyncLane /*0b0000000000000000000000000000001*/
)
// => true. SyncLane is not Idle task
isSubsetOfLanes(
NonIdleLanes, /*0b0001111111111111111111111111111*/
OffscreenLane /*0b1000000000000000000000000000000*/
)
// => false. OffscreenLane is Idle task
isSubsetOfLanes(
TransitionLanes, /*0b0000000001111111111111111000000*/
TransitionLane1 /*0b0000000000000000000000001000000*/
)
// => true. TransitionLane1 is included in TransitionLanes
isSubsetOfLanes
allows you to determine if the corresponding Lane is a subset of the target Fiber. scheduleWorkOnParentPath
. This function, roughly speaking, is responsible for notifying the upper level parent that the lower level child has a task.// https://github.com/facebook/react/blob/a8964649bb6332cf1f8d723f81ce97cc5a1886ff/packages/react-reconciler/src/ReactFiberNewContext.new.js#L142
export function scheduleWorkOnParentPath(
parent: Fiber | null,
renderLanes: Lanes,
) {
// Update the child lanes of all the ancestors, including the alternates.
let node = parent;
while (node !== null) {
const alternate = node.alternate;
if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
node.childLanes = mergeLanes(node.childLanes, renderLanes);
if (alternate !== null) {
alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
}
} else if (
alternate !== null &&
!isSubsetOfLanes(alternate.childLanes, renderLanes)
) {
alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
} else {
// Neither alternate was updated, which means the rest of the
// ancestor path already has sufficient priority.
break;
}
node = node.return;
}
}
node.return
is the Fiber of a parent or multiple parents, so you can see that it is a function that updates childLanes by following the path of the parent in order. For example, it can be used to tell the parent when the React.Context is updated in children.isSubsetOfLanes
is used.if (!isSubsetOfLanes(node.childLanes, renderLanes)) {
node.childLanes = mergeLanes(node.childLanes, renderLanes);
if (alternate !== null) {
alternate.childLanes = mergeLanes(alternate.childLanes, renderLanes);
}
} else if (
node.childLanes
in the code) is not a subset of the target Lane, update parent.childLanes to the value merged with the target Lane." By doing this, we can move the lanes of children to the parent side. As a result, if you look at fiber.childrenLanes at reconcile time, you will know that the lower layer needs to be re-rendered.