Skip to content

Commit 67a05d0

Browse files
authored
fix[devtools]: fixed duplicated backend activation with multiple renderers (#26807)
## Summary Initially reported in #26797. Was not able to reproduce the exact same problem, but found this case: 1. Open corresponding codepen from the issue in debug mode 2. Open components tab of the extension 3. Refresh the page Received multiple errors: - Warning in the Console tab: Invalid renderer id "2". - Error in the Components tab: Uncaught Error: Cannot add node "3" because a node with that id is already in the Store. This problem has occurred after landing a fix in #26779. Looks like Chrome is keeping the injected scripts (the backend in this case) and we start backend twice.
1 parent df12d7e commit 67a05d0

File tree

2 files changed

+14
-4
lines changed

2 files changed

+14
-4
lines changed

packages/react-devtools-extensions/src/backend.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,5 +29,6 @@ function setup(hook: ?DevToolsHook) {
2929
initBackend,
3030
setupNativeStyleEditor,
3131
});
32+
3233
hook.emit('devtools-backend-installed', COMPACT_VERSION_NAME);
3334
}

packages/react-devtools-extensions/src/backendManager.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ function setup(hook: ?DevToolsHook) {
5858

5959
// register renderers that have already injected themselves.
6060
hook.renderers.forEach(renderer => {
61-
registerRenderer(renderer);
61+
registerRenderer(renderer, hook);
6262
});
6363

6464
// Activate and remove from required all present backends, registered within the hook
@@ -71,7 +71,7 @@ function setup(hook: ?DevToolsHook) {
7171

7272
// register renderers that inject themselves later.
7373
hook.sub('renderer', ({renderer}) => {
74-
registerRenderer(renderer);
74+
registerRenderer(renderer, hook);
7575
updateRequiredBackends();
7676
});
7777

@@ -84,19 +84,24 @@ function setup(hook: ?DevToolsHook) {
8484

8585
const requiredBackends = new Set<string>();
8686

87-
function registerRenderer(renderer: ReactRenderer) {
87+
function registerRenderer(renderer: ReactRenderer, hook: DevToolsHook) {
8888
let version = renderer.reconcilerVersion || renderer.version;
8989
if (!hasAssignedBackend(version)) {
9090
version = COMPACT_VERSION_NAME;
9191
}
92-
requiredBackends.add(version);
92+
93+
// Check if required backend is already activated, no need to require again
94+
if (!hook.backends.has(version)) {
95+
requiredBackends.add(version);
96+
}
9397
}
9498

9599
function activateBackend(version: string, hook: DevToolsHook) {
96100
const backend = hook.backends.get(version);
97101
if (!backend) {
98102
throw new Error(`Could not find backend for version "${version}"`);
99103
}
104+
100105
const {Agent, Bridge, initBackend, setupNativeStyleEditor} = backend;
101106
const bridge = new Bridge({
102107
listen(fn) {
@@ -157,6 +162,10 @@ function activateBackend(version: string, hook: DevToolsHook) {
157162

158163
// tell the service worker which versions of backends are needed for the current page
159164
function updateRequiredBackends() {
165+
if (requiredBackends.size === 0) {
166+
return;
167+
}
168+
160169
window.postMessage(
161170
{
162171
source: 'react-devtools-backend-manager',

0 commit comments

Comments
 (0)