Skip to content

Commit a4ae4d6

Browse files
committed
Untrack Fiber by walking the Fiber tree
If we have any filtered children, we need to untrack those as well.
1 parent 47a1fa8 commit a4ae4d6

File tree

1 file changed

+56
-49
lines changed
  • packages/react-devtools-shared/src/backend/fiber

1 file changed

+56
-49
lines changed

packages/react-devtools-shared/src/backend/fiber/renderer.js

+56-49
Original file line numberDiff line numberDiff line change
@@ -1525,63 +1525,30 @@ export function attach(
15251525

15261526
// Removes a Fiber (and its alternate) from the Maps used to track their id.
15271527
// This method should always be called when a Fiber is unmounting.
1528-
function untrackFiber(fiberInstance: FiberInstance) {
1528+
function untrackFiber(nearestInstance: DevToolsInstance, fiber: Fiber) {
15291529
if (__DEBUG__) {
1530-
debug('untrackFiber()', fiberInstance.data, null);
1530+
debug('untrackFiber()', fiber, null);
15311531
}
1532+
// TODO: Consider using a WeakMap instead. The only thing where that doesn't work
1533+
// is React Native Paper which tracks tags but that support is eventually going away
1534+
// and can use the old findFiberByHostInstance strategy.
15321535

1533-
idToDevToolsInstanceMap.delete(fiberInstance.id);
1534-
1535-
const fiber = fiberInstance.data;
1536-
1537-
// Restore any errors/warnings associated with this fiber to the pending
1538-
// map. I.e. treat it as before we tracked the instances. This lets us
1539-
// restore them if we remount the same Fibers later. Otherwise we rely
1540-
// on the GC of the Fibers to clean them up.
1541-
if (fiberInstance.errors !== null) {
1542-
pendingFiberToErrorsMap.set(fiber, fiberInstance.errors);
1543-
fiberInstance.errors = null;
1544-
}
1545-
if (fiberInstance.warnings !== null) {
1546-
pendingFiberToWarningsMap.set(fiber, fiberInstance.warnings);
1547-
fiberInstance.warnings = null;
1548-
}
1549-
1550-
if (fiberInstance.flags & FORCE_ERROR) {
1551-
fiberInstance.flags &= ~FORCE_ERROR;
1552-
forceErrorCount--;
1553-
if (forceErrorCount === 0 && setErrorHandler != null) {
1554-
setErrorHandler(shouldErrorFiberAlwaysNull);
1555-
}
1556-
}
1557-
if (fiberInstance.flags & FORCE_SUSPENSE_FALLBACK) {
1558-
fiberInstance.flags &= ~FORCE_SUSPENSE_FALLBACK;
1559-
forceFallbackCount--;
1560-
if (forceFallbackCount === 0 && setSuspenseHandler != null) {
1561-
setSuspenseHandler(shouldSuspendFiberAlwaysFalse);
1562-
}
1563-
}
1564-
1565-
if (fiberToFiberInstanceMap.get(fiber) === fiberInstance) {
1566-
fiberToFiberInstanceMap.delete(fiber);
1567-
}
1568-
const {alternate} = fiber;
1569-
if (alternate !== null) {
1570-
if (fiberToFiberInstanceMap.get(alternate) === fiberInstance) {
1571-
fiberToFiberInstanceMap.delete(alternate);
1572-
}
1573-
}
1574-
1575-
// TODO: This is not enough if this Fiber was filtered since we don't end up
1576-
// untracking it. We could use a WeakMap but that doesn't work for Paper tags.
15771536
if (fiber.tag === HostHoistable) {
1578-
releaseHostResource(fiberInstance, fiber.memoizedState);
1537+
releaseHostResource(nearestInstance, fiber.memoizedState);
15791538
} else if (
15801539
fiber.tag === HostComponent ||
15811540
fiber.tag === HostText ||
15821541
fiber.tag === HostSingleton
15831542
) {
1584-
releaseHostInstance(fiberInstance, fiber.stateNode);
1543+
releaseHostInstance(nearestInstance, fiber.stateNode);
1544+
}
1545+
1546+
// Recursively clean up any filtered Fibers below this one as well since
1547+
// we won't recordUnmount on those.
1548+
for (let child = fiber.child; child !== null; child = child.sibling) {
1549+
if (shouldFilterFiber(child)) {
1550+
untrackFiber(nearestInstance, child);
1551+
}
15851552
}
15861553
}
15871554

@@ -2425,7 +2392,47 @@ export function attach(
24252392
pendingRealUnmountedIDs.push(id);
24262393
}
24272394

2428-
untrackFiber(fiberInstance);
2395+
idToDevToolsInstanceMap.delete(fiberInstance.id);
2396+
2397+
// Restore any errors/warnings associated with this fiber to the pending
2398+
// map. I.e. treat it as before we tracked the instances. This lets us
2399+
// restore them if we remount the same Fibers later. Otherwise we rely
2400+
// on the GC of the Fibers to clean them up.
2401+
if (fiberInstance.errors !== null) {
2402+
pendingFiberToErrorsMap.set(fiber, fiberInstance.errors);
2403+
fiberInstance.errors = null;
2404+
}
2405+
if (fiberInstance.warnings !== null) {
2406+
pendingFiberToWarningsMap.set(fiber, fiberInstance.warnings);
2407+
fiberInstance.warnings = null;
2408+
}
2409+
2410+
if (fiberInstance.flags & FORCE_ERROR) {
2411+
fiberInstance.flags &= ~FORCE_ERROR;
2412+
forceErrorCount--;
2413+
if (forceErrorCount === 0 && setErrorHandler != null) {
2414+
setErrorHandler(shouldErrorFiberAlwaysNull);
2415+
}
2416+
}
2417+
if (fiberInstance.flags & FORCE_SUSPENSE_FALLBACK) {
2418+
fiberInstance.flags &= ~FORCE_SUSPENSE_FALLBACK;
2419+
forceFallbackCount--;
2420+
if (forceFallbackCount === 0 && setSuspenseHandler != null) {
2421+
setSuspenseHandler(shouldSuspendFiberAlwaysFalse);
2422+
}
2423+
}
2424+
2425+
if (fiberToFiberInstanceMap.get(fiber) === fiberInstance) {
2426+
fiberToFiberInstanceMap.delete(fiber);
2427+
}
2428+
const {alternate} = fiber;
2429+
if (alternate !== null) {
2430+
if (fiberToFiberInstanceMap.get(alternate) === fiberInstance) {
2431+
fiberToFiberInstanceMap.delete(alternate);
2432+
}
2433+
}
2434+
2435+
untrackFiber(fiberInstance, fiber);
24292436
}
24302437

24312438
// Running state of the remaining children from the previous version of this parent that

0 commit comments

Comments
 (0)