[DevTools] Fix crash when revealing stable, filtered `<Activity>` children (#35734)
Sebastian "Sebbie" Silbermann committed
Feb 9, 2026 at 22:52 UTC
4c9d62d2b47be424ad9050725d8bdd8df12fe2a3
2 files changed
+55
packages/react-devtools-shared/src/__tests__/store-test.js
+44
@@ -3572,4 +3572,48 @@ describe('Store', () => {
3572
<Suspense name="inner" rects={[{x:1,y:2,width:14,height:1}]}>
3573
`);
3574
});
3575
+
3576
+ // @reactVersion >= 19
3577
+ it('can reconcile newly visible Activity with filtered, stable children', async () => {
3578
+ const Activity = React.Activity || React.unstable_Activity;
3579
+
3580
+ function IgnoreMe({children}) {
3581
+ return children;
3582
+ }
3583
+
3584
+ function Component({children}) {
3585
+ return <div>{children}</div>;
3586
+ }
3587
+
3588
+ await actAsync(
3589
+ async () =>
3590
+ (store.componentFilters = [createDisplayNameFilter('^IgnoreMe', true)]),
3591
+ );
3592
+
3593
+ const children = (
3594
+ <IgnoreMe>
3595
+ <Component key="left">Left</Component>
3596
+ </IgnoreMe>
3597
+ );
3598
+
3599
+ await actAsync(() => {
3600
+ render(<Activity mode="hidden">{children}</Activity>);
3601
+ });
3602
+
3603
+ expect(store).toMatchInlineSnapshot(`
3604
+ [root]
3605
+ <Activity>
3606
+ `);
3607
+
3608
+ await actAsync(() => {
3609
+ render(<Activity mode="visible">{children}</Activity>);
3610
+ });
3611
+
3612
+ expect(store).toMatchInlineSnapshot(`
3613
+ [root]
3614
+ ▾ <Activity>
3615
+ ▾ <Component key="left">
3616
+ <div>
3617
+ `);
3618
+ });
3619
});
packages/react-devtools-shared/src/backend/fiber/renderer.js
+11
@@ -5416,6 +5416,17 @@ export function attach(
5416
// We're hiding the children. Remove them from the Frontend
5417
unmountRemainingChildren();
5418
}
5419
+ } else if (prevWasHidden && !nextIsHidden) {
5420
+ // Since we don't mount hidden children and unmount children when hiding,
5421
+ // we need to enter the mount path when revealing.
5422
+ const nextChildSet = nextFiber.child;
5423
+ if (nextChildSet !== null) {
5424
+ mountChildrenRecursively(
5425
+ nextChildSet,
5426
+ traceNearestHostComponentUpdate,
5427
+ );
5428
+ updateFlags |= ShouldResetChildren | ShouldResetSuspenseChildren;
5429
+ }
5430
} else if (
5431
nextFiber.tag === SuspenseComponent &&
5432
OffscreenComponent !== -1 &&