diff --git a/packages/react-babylonjs/src/render.ts b/packages/react-babylonjs/src/render.ts index d51b90de..5d10b7c1 100644 --- a/packages/react-babylonjs/src/render.ts +++ b/packages/react-babylonjs/src/render.ts @@ -32,6 +32,38 @@ const ReconcilerPrimary: ReconcilerType = Reconci isPrimaryRenderer: true, }) +/** + * Registers a reconciler with React DevTools exactly once per reconciler + * instance. Without this guard, injectIntoDevTools was being called again + * every time a root was (re)created - e.g. unmounting/remounting a + * by changing its `key` - which re-registers the renderer with the global + * `__REACT_DEVTOOLS_GLOBAL_HOOK__` on every remount. + */ +function injectDevToolsOnce(reconciler: ReconcilerType): void { + if ((reconciler as any).__rbjsDevToolsInjected === true) { + return + } + + if (typeof (reconciler as any).injectIntoDevTools !== 'function') { + return + } + + try { + reconciler.injectIntoDevTools({ + bundleType: process.env.NODE_ENV === 'production' ? 1 : 0, + version, + rendererPackageName: 'react-babylonjs', + findFiberByHostInstance: (reconciler as any).findFiberByHostInstance || null, + }) + } catch (e) { + console.warn('Could not inject into DevTools:', e) + } finally { + // Mark as injected even on failure - retrying on every render for a + // permanently failing injectIntoDevTools call is not useful. + ;(reconciler as any).__rbjsDevToolsInjected = true + } +} + /** * This is a work in progress in experimental state. */ @@ -108,21 +140,10 @@ export function createReconciler(rendererOptions: RendererOptions): ReconcilerIn } roots.set(container, root) - - if (typeof (reconciler as any).injectIntoDevTools === 'function') { - try { - reconciler.injectIntoDevTools({ - bundleType: process.env.NODE_ENV === 'production' ? 1 : 0, - version, - rendererPackageName: 'react-babylonjs', - findFiberByHostInstance: (reconciler as any).findFiberByHostInstance || null, - }) - } catch (e) { - console.warn('Could not inject into DevTools:', e) - } - } } + injectDevToolsOnce(reconciler) + try { // The updateContainer call might have changed in React 19 reconciler.updateContainer(element, root, parentComponent, callback)