mirror of
https://github.com/zebrajr/react.git
synced 2025-12-06 00:20:04 +01:00
[DevTools] Handle LegacyHidden Fibers like Offscreen Fibers. (#34564)
This commit is contained in:
parent
83c88ad470
commit
012b371cde
|
|
@ -725,14 +725,14 @@ describe('ProfilingCache', () => {
|
|||
const commitData = store.profilerStore.getDataForRoot(rootID).commitData;
|
||||
expect(commitData).toHaveLength(2);
|
||||
|
||||
const isLegacySuspense = React.version.startsWith('17');
|
||||
if (isLegacySuspense) {
|
||||
if (React.version.startsWith('17')) {
|
||||
// React 17 will mount all children until it suspends in a LegacyHidden
|
||||
// The ID gap is from the Fiber for <Async> that's in the disconnected tree.
|
||||
expect(commitData[0].fiberActualDurations).toMatchInlineSnapshot(`
|
||||
Map {
|
||||
1 => 15,
|
||||
2 => 15,
|
||||
3 => 5,
|
||||
4 => 3,
|
||||
5 => 2,
|
||||
}
|
||||
`);
|
||||
|
|
@ -741,7 +741,6 @@ describe('ProfilingCache', () => {
|
|||
1 => 0,
|
||||
2 => 10,
|
||||
3 => 3,
|
||||
4 => 3,
|
||||
5 => 2,
|
||||
}
|
||||
`);
|
||||
|
|
|
|||
|
|
@ -19,8 +19,6 @@ describe('commit tree', () => {
|
|||
let Scheduler;
|
||||
let store: Store;
|
||||
let utils;
|
||||
const isLegacySuspense =
|
||||
React.version.startsWith('16') || React.version.startsWith('17');
|
||||
|
||||
beforeEach(() => {
|
||||
utils = require('./utils');
|
||||
|
|
@ -186,24 +184,13 @@ describe('commit tree', () => {
|
|||
utils.act(() => store.profilerStore.startProfiling());
|
||||
utils.act(() => legacyRender(<App renderChildren={true} />));
|
||||
await Promise.resolve();
|
||||
if (isLegacySuspense) {
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
▾ <App>
|
||||
▾ <Suspense>
|
||||
<Lazy>
|
||||
[suspense-root] rects={null}
|
||||
<Suspense name="App" rects={null}>
|
||||
`);
|
||||
} else {
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
▾ <App>
|
||||
<Suspense>
|
||||
[suspense-root] rects={null}
|
||||
<Suspense name="App" rects={null}>
|
||||
`);
|
||||
}
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
▾ <App>
|
||||
<Suspense>
|
||||
[suspense-root] rects={null}
|
||||
<Suspense name="App" rects={null}>
|
||||
`);
|
||||
utils.act(() => legacyRender(<App renderChildren={true} />));
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
|
|
@ -231,13 +218,7 @@ describe('commit tree', () => {
|
|||
);
|
||||
}
|
||||
|
||||
expect(commitTrees[0].nodes.size).toBe(
|
||||
isLegacySuspense
|
||||
? // <Root> + <App> + <Suspense> + <Lazy>
|
||||
4
|
||||
: // <Root> + <App> + <Suspense>
|
||||
3,
|
||||
);
|
||||
expect(commitTrees[0].nodes.size).toBe(3);
|
||||
expect(commitTrees[1].nodes.size).toBe(4); // <Root> + <App> + <Suspense> + <LazyInnerComponent>
|
||||
expect(commitTrees[2].nodes.size).toBe(2); // <Root> + <App>
|
||||
});
|
||||
|
|
@ -291,24 +272,13 @@ describe('commit tree', () => {
|
|||
it('should support Lazy components that are unmounted before resolving (legacy render)', async () => {
|
||||
utils.act(() => store.profilerStore.startProfiling());
|
||||
utils.act(() => legacyRender(<App renderChildren={true} />));
|
||||
if (isLegacySuspense) {
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
▾ <App>
|
||||
▾ <Suspense>
|
||||
<Lazy>
|
||||
[suspense-root] rects={null}
|
||||
<Suspense name="App" rects={null}>
|
||||
`);
|
||||
} else {
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
▾ <App>
|
||||
<Suspense>
|
||||
[suspense-root] rects={null}
|
||||
<Suspense name="App" rects={null}>
|
||||
`);
|
||||
}
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
▾ <App>
|
||||
<Suspense>
|
||||
[suspense-root] rects={null}
|
||||
<Suspense name="App" rects={null}>
|
||||
`);
|
||||
utils.act(() => legacyRender(<App renderChildren={false} />));
|
||||
expect(store).toMatchInlineSnapshot(`
|
||||
[root]
|
||||
|
|
@ -327,13 +297,7 @@ describe('commit tree', () => {
|
|||
);
|
||||
}
|
||||
|
||||
expect(commitTrees[0].nodes.size).toBe(
|
||||
isLegacySuspense
|
||||
? // <Root> + <App> + <Suspense> + <Lazy>
|
||||
4
|
||||
: // <Root> + <App> + <Suspense>
|
||||
3,
|
||||
);
|
||||
expect(commitTrees[0].nodes.size).toBe(3);
|
||||
expect(commitTrees[1].nodes.size).toBe(2); // <Root> + <App>
|
||||
});
|
||||
|
||||
|
|
|
|||
|
|
@ -2828,7 +2828,7 @@ describe('Store', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
// @reactVersion >= 18.0
|
||||
// @reactVersion >= 17.0
|
||||
it('can reconcile Suspense in fallback positions', async () => {
|
||||
let resolveFallback;
|
||||
const fallbackPromise = new Promise(resolve => {
|
||||
|
|
@ -2907,7 +2907,7 @@ describe('Store', () => {
|
|||
`);
|
||||
});
|
||||
|
||||
// @reactVersion >= 18.0
|
||||
// @reactVersion >= 17.0
|
||||
it('can reconcile resuspended Suspense with Suspense in fallback positions', async () => {
|
||||
let resolveHeadFallback;
|
||||
let resolveHeadContent;
|
||||
|
|
|
|||
|
|
@ -460,10 +460,10 @@ export function getInternalReactConstants(version: string): {
|
|||
IncompleteFunctionComponent: 28,
|
||||
IndeterminateComponent: 2, // removed in 19.0.0
|
||||
LazyComponent: 16,
|
||||
LegacyHiddenComponent: 23,
|
||||
LegacyHiddenComponent: 23, // Does not exist in 18+ OSS but exists in fb builds
|
||||
MemoComponent: 14,
|
||||
Mode: 8,
|
||||
OffscreenComponent: 22, // Experimental
|
||||
OffscreenComponent: 22, // Experimental in 17. Stable in 18+
|
||||
Profiler: 12,
|
||||
ScopeComponent: 21, // Experimental
|
||||
SimpleMemoComponent: 15,
|
||||
|
|
@ -3057,13 +3057,23 @@ export function attach(
|
|||
}
|
||||
}
|
||||
|
||||
function isHiddenOffscreen(fiber: Fiber): boolean {
|
||||
switch (fiber.tag) {
|
||||
case LegacyHiddenComponent:
|
||||
// fallthrough since all published implementations currently implement the same state as Offscreen.
|
||||
case OffscreenComponent:
|
||||
return fiber.memoizedState !== null;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
function unmountRemainingChildren() {
|
||||
if (
|
||||
reconcilingParent !== null &&
|
||||
(reconcilingParent.kind === FIBER_INSTANCE ||
|
||||
reconcilingParent.kind === FILTERED_FIBER_INSTANCE) &&
|
||||
reconcilingParent.data.tag === OffscreenComponent &&
|
||||
reconcilingParent.data.memoizedState !== null &&
|
||||
isHiddenOffscreen(reconcilingParent.data) &&
|
||||
!isInDisconnectedSubtree
|
||||
) {
|
||||
// This is a hidden offscreen, we need to execute this in the context of a disconnected subtree.
|
||||
|
|
@ -3170,8 +3180,7 @@ export function attach(
|
|||
if (
|
||||
(parent.kind === FIBER_INSTANCE ||
|
||||
parent.kind === FILTERED_FIBER_INSTANCE) &&
|
||||
parent.data.tag === OffscreenComponent &&
|
||||
parent.data.memoizedState !== null
|
||||
isHiddenOffscreen(parent.data)
|
||||
) {
|
||||
// We're inside a hidden offscreen Fiber. We're in a disconnected tree.
|
||||
return;
|
||||
|
|
@ -3819,7 +3828,9 @@ export function attach(
|
|||
(reconcilingParent !== null &&
|
||||
reconcilingParent.kind === VIRTUAL_INSTANCE) ||
|
||||
fiber.tag === SuspenseComponent ||
|
||||
fiber.tag === OffscreenComponent // Use to keep resuspended instances alive inside a SuspenseComponent.
|
||||
// Use to keep resuspended instances alive inside a SuspenseComponent.
|
||||
fiber.tag === OffscreenComponent ||
|
||||
fiber.tag === LegacyHiddenComponent
|
||||
) {
|
||||
// If the parent is a Virtual Instance and we filtered this Fiber we include a
|
||||
// hidden node. We also include this if it's a Suspense boundary so we can track those
|
||||
|
|
@ -3939,7 +3950,7 @@ export function attach(
|
|||
trackDebugInfoFromHostComponent(nearestInstance, fiber);
|
||||
}
|
||||
|
||||
if (fiber.tag === OffscreenComponent && fiber.memoizedState !== null) {
|
||||
if (isHiddenOffscreen(fiber)) {
|
||||
// If an Offscreen component is hidden, mount its children as disconnected.
|
||||
const stashedDisconnected = isInDisconnectedSubtree;
|
||||
isInDisconnectedSubtree = true;
|
||||
|
|
@ -4261,7 +4272,7 @@ export function attach(
|
|||
while (child !== null) {
|
||||
if (child.kind === FILTERED_FIBER_INSTANCE) {
|
||||
const fiber = child.data;
|
||||
if (fiber.tag === OffscreenComponent && fiber.memoizedState !== null) {
|
||||
if (isHiddenOffscreen(fiber)) {
|
||||
// The children of this Offscreen are hidden so they don't get added.
|
||||
} else {
|
||||
addUnfilteredChildrenIDs(child, nextChildren);
|
||||
|
|
@ -4888,9 +4899,8 @@ export function attach(
|
|||
const nextDidTimeOut =
|
||||
isLegacySuspense && nextFiber.memoizedState !== null;
|
||||
|
||||
const isOffscreen = nextFiber.tag === OffscreenComponent;
|
||||
const prevWasHidden = isOffscreen && prevFiber.memoizedState !== null;
|
||||
const nextIsHidden = isOffscreen && nextFiber.memoizedState !== null;
|
||||
const prevWasHidden = isHiddenOffscreen(prevFiber);
|
||||
const nextIsHidden = isHiddenOffscreen(nextFiber);
|
||||
|
||||
if (isLegacySuspense) {
|
||||
if (
|
||||
|
|
@ -5245,8 +5255,7 @@ export function attach(
|
|||
if (
|
||||
(child.kind === FIBER_INSTANCE ||
|
||||
child.kind === FILTERED_FIBER_INSTANCE) &&
|
||||
child.data.tag === OffscreenComponent &&
|
||||
child.data.memoizedState !== null
|
||||
isHiddenOffscreen(child.data)
|
||||
) {
|
||||
// This instance's children are already disconnected.
|
||||
} else {
|
||||
|
|
@ -5275,8 +5284,7 @@ export function attach(
|
|||
if (
|
||||
(child.kind === FIBER_INSTANCE ||
|
||||
child.kind === FILTERED_FIBER_INSTANCE) &&
|
||||
child.data.tag === OffscreenComponent &&
|
||||
child.data.memoizedState !== null
|
||||
isHiddenOffscreen(child.data)
|
||||
) {
|
||||
// This instance's children should remain disconnected.
|
||||
} else {
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user