Skip to content

Commit d66fa02

Browse files
authored
fix: use public instance in Fiber renderer and expose it from getInspectorDataForViewAtPoint (#31068)
React DevTools no longer operates with just Fibers, it now builds its own Shadow Tree, which represents the tree on the Host (Fabric on Native, DOM on Web). We have to keep track of public instances for a select-to-inspect feature. We've recently changed this logic in #30831, and looks like we've been incorrectly getting a public instance for Fabric case. Not only this, turns out that all `getInspectorData...` APIs are returning Fibers, and not public instances. I have to expose it, so that React DevTools can correctly identify the element, which was selected. Changes for React Native are in [D63421463](https://www.internalfb.com/diff/D63421463)
1 parent 778e1ed commit d66fa02

File tree

3 files changed

+26
-7
lines changed

3 files changed

+26
-7
lines changed

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

Lines changed: 21 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -763,16 +763,30 @@ const hostResourceToDevToolsInstanceMap: Map<
763763
Set<DevToolsInstance>,
764764
> = new Map();
765765

766+
// Ideally, this should be injected from Reconciler config
766767
function getPublicInstance(instance: HostInstance): HostInstance {
767768
// Typically the PublicInstance and HostInstance is the same thing but not in Fabric.
768769
// So we need to detect this and use that as the public instance.
769-
return typeof instance === 'object' &&
770-
instance !== null &&
771-
typeof instance.canonical === 'object'
772-
? (instance.canonical: any)
773-
: typeof instance._nativeTag === 'number'
774-
? instance._nativeTag
775-
: instance;
770+
771+
// React Native. Modern. Fabric.
772+
if (typeof instance === 'object' && instance !== null) {
773+
if (typeof instance.canonical === 'object' && instance.canonical !== null) {
774+
if (
775+
typeof instance.canonical.publicInstance === 'object' &&
776+
instance.canonical.publicInstance !== null
777+
) {
778+
return instance.canonical.publicInstance;
779+
}
780+
}
781+
782+
// React Native. Legacy. Paper.
783+
if (typeof instance._nativeTag === 'number') {
784+
return instance._nativeTag;
785+
}
786+
}
787+
788+
// React Web. Usually a DOM element.
789+
return instance;
776790
}
777791

778792
function aquireHostInstance(

packages/react-native-renderer/src/ReactNativeFiberInspector.js

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -209,6 +209,8 @@ function getInspectorDataForViewAtPoint(
209209

210210
closestInstance =
211211
internalInstanceHandle.stateNode.canonical.internalInstanceHandle;
212+
const closestPublicInstance =
213+
internalInstanceHandle.stateNode.canonical.publicInstance;
212214

213215
// Note: this is deprecated and we want to remove it ASAP. Keeping it here for React DevTools compatibility for now.
214216
const nativeViewTag =
@@ -224,6 +226,7 @@ function getInspectorDataForViewAtPoint(
224226
pointerY: locationY,
225227
frame: {left: pageX, top: pageY, width, height},
226228
touchedViewTag: nativeViewTag,
229+
closestPublicInstance,
227230
});
228231
},
229232
);
@@ -243,6 +246,7 @@ function getInspectorDataForViewAtPoint(
243246
pointerY: locationY,
244247
frame: {left, top, width, height},
245248
touchedViewTag: nativeViewTag,
249+
closestPublicInstance: nativeViewTag,
246250
});
247251
},
248252
);

packages/react-native-renderer/src/ReactNativeTypes.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,7 @@ export type TouchedViewDataAtPoint = $ReadOnly<{
179179
width: number,
180180
height: number,
181181
}>,
182+
closestPublicInstance?: PublicInstance,
182183
...InspectorData,
183184
}>;
184185

0 commit comments

Comments
 (0)