Skip to content

Commit cdb39b7

Browse files
Brian Vaughnkoto
authored andcommitted
DevTools: Support an element mounting before its owner (facebook#21562)
1 parent 54f9106 commit cdb39b7

File tree

2 files changed

+46
-1
lines changed

2 files changed

+46
-1
lines changed

packages/react-devtools-shared/src/__tests__/store-test.js

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,45 @@ describe('Store', () => {
6060
expect(store).toMatchSnapshot('2: add host nodes');
6161
});
6262

63+
// This test is not the same cause as what's reported on GitHub,
64+
// but the resulting behavior (owner mounting after descendant) is the same.
65+
// Thec ase below is admittedly contrived and relies on side effects.
66+
// I'mnot yet sure of how to reduce the GitHub reported production case to a test though.
67+
// See https://github.com/facebook/react/issues/21445
68+
it('should handle when a component mounts before its owner', () => {
69+
const promise = new Promise(resolve => {});
70+
71+
let Dynamic = null;
72+
const Owner = () => {
73+
Dynamic = <Child />;
74+
throw promise;
75+
};
76+
const Parent = () => {
77+
return Dynamic;
78+
};
79+
const Child = () => null;
80+
81+
const container = document.createElement('div');
82+
83+
act(() =>
84+
ReactDOM.render(
85+
<>
86+
<React.Suspense fallback="Loading...">
87+
<Owner />
88+
</React.Suspense>
89+
<Parent />
90+
</>,
91+
container,
92+
),
93+
);
94+
expect(store).toMatchInlineSnapshot(`
95+
[root]
96+
<Suspense>
97+
▾ <Parent>
98+
<Child>
99+
`);
100+
});
101+
63102
describe('collapseNodesByDefault:false', () => {
64103
beforeEach(() => {
65104
store.collapseNodesByDefault = false;

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1753,7 +1753,13 @@ export function attach(
17531753
const elementType = getElementTypeForFiber(fiber);
17541754
const {_debugOwner} = fiber;
17551755

1756-
const ownerID = _debugOwner != null ? getFiberIDThrows(_debugOwner) : 0;
1756+
// Ideally we should call getFiberIDThrows() for _debugOwner,
1757+
// since owners are almost always higher in the tree (and so have already been processed),
1758+
// but in some (rare) instances reported in open source, a descendant mounts before an owner.
1759+
// Since this is a DEV only field it's probably okay to also just lazily generate and ID here if needed.
1760+
// See https://github.com/facebook/react/issues/21445
1761+
const ownerID =
1762+
_debugOwner != null ? getOrGenerateFiberID(_debugOwner) : 0;
17571763
const parentID = parentFiber ? getFiberIDThrows(parentFiber) : 0;
17581764

17591765
const displayNameStringID = getStringID(displayName);

0 commit comments

Comments
 (0)