Skip to content

Commit 38bea8c

Browse files
committed
fix[devtools]: allow element updates polling only if bridge is alive
1 parent 035a41c commit 38bea8c

File tree

2 files changed

+42
-25
lines changed

2 files changed

+42
-25
lines changed

packages/react-devtools-shared/src/devtools/views/Components/InspectedElementContext.js

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,8 @@ export function InspectedElementContextController({
107107
parseHookNamesByDefault || alreadyLoadedHookNames,
108108
);
109109

110+
const [bridgeIsAlive, setBridgeIsAliveStatus] = useState<boolean>(true);
111+
110112
const elementHasChanged = element !== null && element !== state.element;
111113

112114
// Reset the cached inspected paths when a new element is selected.
@@ -213,14 +215,25 @@ export function InspectedElementContextController({
213215
}
214216
}, [state]);
215217

218+
useEffect(() => {
219+
// Assuming that new bridge is always alive at this moment
220+
setBridgeIsAliveStatus(true);
221+
222+
const listener = () => setBridgeIsAliveStatus(false);
223+
bridge.addListener('shutdown', listener);
224+
225+
return () => bridge.removeListener('shutdown', bridge);
226+
}, [bridge]);
227+
216228
// Periodically poll the selected element for updates.
217229
useEffect(() => {
218-
if (element !== null) {
230+
if (element !== null && bridgeIsAlive) {
219231
const checkForUpdateWrapper = () => {
220232
checkForUpdate({bridge, element, refresh, store});
221233
timeoutID = setTimeout(checkForUpdateWrapper, POLL_INTERVAL);
222234
};
223235
let timeoutID = setTimeout(checkForUpdateWrapper, POLL_INTERVAL);
236+
224237
return () => {
225238
clearTimeout(timeoutID);
226239
};
@@ -232,6 +245,7 @@ export function InspectedElementContextController({
232245
// No sense to ping right away after e.g. inspecting/hydrating a path.
233246
inspectedElement,
234247
state,
248+
bridgeIsAlive,
235249
]);
236250

237251
const value = useMemo<Context>(

packages/react-devtools-shared/src/inspectedElementCache.js

Lines changed: 27 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -180,32 +180,35 @@ export function checkForUpdate({
180180
}): void {
181181
const {id} = element;
182182
const rendererID = store.getRendererIDForElement(id);
183-
if (rendererID != null) {
184-
inspectElementMutableSource({
185-
bridge,
186-
element,
187-
path: null,
188-
rendererID: ((rendererID: any): number),
189-
}).then(
190-
([inspectedElement, responseType]: [
191-
InspectedElementFrontend,
192-
InspectedElementResponseType,
193-
]) => {
194-
if (responseType === 'full-data') {
195-
startTransition(() => {
196-
const [key, value] = createCacheSeed(element, inspectedElement);
197-
refresh(key, value);
198-
});
199-
}
200-
},
201183

202-
// There isn't much to do about errors in this case,
203-
// but we should at least log them so they aren't silent.
204-
error => {
205-
console.error(error);
206-
},
207-
);
184+
if (rendererID == null) {
185+
return;
208186
}
187+
188+
inspectElementMutableSource({
189+
bridge,
190+
element,
191+
path: null,
192+
rendererID,
193+
}).then(
194+
([inspectedElement, responseType]: [
195+
InspectedElementFrontend,
196+
InspectedElementResponseType,
197+
]) => {
198+
if (responseType === 'full-data') {
199+
startTransition(() => {
200+
const [key, value] = createCacheSeed(element, inspectedElement);
201+
refresh(key, value);
202+
});
203+
}
204+
},
205+
206+
// There isn't much to do about errors in this case,
207+
// but we should at least log them so they aren't silent.
208+
error => {
209+
console.error(error);
210+
},
211+
);
209212
}
210213

211214
export function clearCacheBecauseOfError(refresh: RefreshFunction): void {

0 commit comments

Comments
 (0)