Skip to content

Commit 514a6cd

Browse files
rubennortefacebook-github-bot
authored andcommitted
Guard against unmounted components when using traversal APIs (facebook#41451)
Summary: After [this change in React](facebook/react#27687), `ReactFabric.getPublicInstanceFromInternalInstanceHandle` can return `null` if the instance handle is a fiber that was unmounted (before that PR, it would throw an error). This modifies the DOM traversal API to gracefully handle that case. Changelog: [internal] Reviewed By: rshest Differential Revision: D51210455
1 parent 5b3a4bd commit 514a6cd

File tree

2 files changed

+10
-6
lines changed

2 files changed

+10
-6
lines changed

packages/react-native/Libraries/DOM/Nodes/ReactNativeElement.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ export default class ReactNativeElement
9090
offsetParentInstanceHandle,
9191
);
9292
// $FlowExpectedError[incompatible-type] The value returned by `getOffset` is always an instance handle for `ReadOnlyElement`.
93-
const offsetParentElement: ReadOnlyElement = offsetParent;
93+
const offsetParentElement: ReadOnlyElement | null = offsetParent;
9494
return offsetParentElement;
9595
}
9696
}

packages/react-native/Libraries/DOM/Nodes/ReadOnlyNode.js

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ export default class ReadOnlyNode {
134134
return null;
135135
}
136136

137-
return getPublicInstanceFromInternalInstanceHandle(parentInstanceHandle);
137+
return (
138+
getPublicInstanceFromInternalInstanceHandle(parentInstanceHandle) ?? null
139+
);
138140
}
139141

140142
get previousSibling(): ReadOnlyNode | null {
@@ -322,9 +324,11 @@ export function getChildNodes(
322324
const childNodeInstanceHandles = nullthrows(
323325
getFabricUIManager(),
324326
).getChildNodes(shadowNode);
325-
return childNodeInstanceHandles.map(instanceHandle =>
326-
getPublicInstanceFromInternalInstanceHandle(instanceHandle),
327-
);
327+
return childNodeInstanceHandles
328+
.map(instanceHandle =>
329+
getPublicInstanceFromInternalInstanceHandle(instanceHandle),
330+
)
331+
.filter(Boolean);
328332
}
329333

330334
function getNodeSiblingsAndPosition(
@@ -348,7 +352,7 @@ function getNodeSiblingsAndPosition(
348352

349353
export function getPublicInstanceFromInternalInstanceHandle(
350354
instanceHandle: InternalInstanceHandle,
351-
): ReadOnlyNode {
355+
): ?ReadOnlyNode {
352356
const mixedPublicInstance =
353357
ReactFabric.getPublicInstanceFromInternalInstanceHandle(instanceHandle);
354358
// $FlowExpectedError[incompatible-return] React defines public instances as "mixed" because it can't access the definition from React Native.

0 commit comments

Comments
 (0)