refactor(getInspectorDataForViewAtPoint): listen to attached renderers (#41202)

Summary:
Pull Request resolved: https://github.com/facebook/react-native/pull/41202

Changelog: [Internal]

Previous implementation only works because `getInspectorDataForViewAtPoint.js` module is evaluated once `Inspector` component is renderered, which is DEV-only and [imported with inline require](https://www.internalfb.com/code/fbsource/[86a4c61a19ad]/xplat/js/react-native-github/packages/react-native/Libraries/ReactNative/AppContainer.js?lines=72).

This also depends on React DevTools' hook being injected.

With these changes, `getInspectorDataForViewAtPoint` can be evaluated at startup, and it also listens to potential renderers attached later

Reviewed By: NickGerleman

Differential Revision: D50649867

fbshipit-source-id: c67426da313a80d7d57c918fe1d177ec685d753a
This commit is contained in:
Ruslan Lesiutin 2023-10-31 09:06:21 -07:00 коммит произвёл Facebook GitHub Bot
Родитель b35914de38
Коммит a286f00073
1 изменённых файлов: 20 добавлений и 8 удалений

Просмотреть файл

@ -28,17 +28,27 @@ export type ReactRenderer = {
...
},
};
type AttachedRendererEventPayload = {id: number, renderer: ReactRenderer};
const hook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
const renderers = findRenderers();
const reactDevToolsHook = window.__REACT_DEVTOOLS_GLOBAL_HOOK__;
invariant(
Boolean(reactDevToolsHook),
'getInspectorDataForViewAtPoint should not be used if React DevTools hook is not injected',
);
function findRenderers(): $ReadOnlyArray<ReactRenderer> {
const allRenderers = Array.from(hook.renderers.values());
const renderers: Array<ReactRenderer> = Array.from(
window.__REACT_DEVTOOLS_GLOBAL_HOOK__.renderers.values(),
);
const appendRenderer = ({renderer}: AttachedRendererEventPayload) =>
renderers.push(renderer);
reactDevToolsHook.on('renderer', appendRenderer);
function validateRenderers(): void {
invariant(
allRenderers.length >= 1,
renderers.length > 0,
'Expected to find at least one React Native renderer on DevTools hook.',
);
return allRenderers;
}
module.exports = function getInspectorDataForViewAtPoint(
@ -47,13 +57,15 @@ module.exports = function getInspectorDataForViewAtPoint(
locationY: number,
callback: (viewData: TouchedViewDataAtPoint) => boolean,
) {
validateRenderers();
let shouldBreak = false;
// Check all renderers for inspector data.
for (let i = 0; i < renderers.length; i++) {
for (const renderer of renderers) {
if (shouldBreak) {
break;
}
const renderer = renderers[i];
if (renderer?.rendererConfig?.getInspectorDataForViewAtPoint != null) {
renderer.rendererConfig.getInspectorDataForViewAtPoint(
inspectedView,