mirror of
https://github.com/facebook/react.git
synced 2025-11-01 09:12:30 +00:00
refactor[react-devtools/extensions]: dont debounce cleanup logic on navigation (#30027)
## Summary There is a race condition in the way we poll if React is on the page and when we actually clear this polling instance. When user navigates to a different page, we will debounce a callback for 500ms, which will: 1. Cleanup previous React polling instance 2. Start a new React polling instance Since the cleanup logic is debounced, there is a small chance that by the time we are going to clean up this polling instance, it will be `eval`-ed on the page, that is using React. For example, when user is navigating from the page which doesn't have React running, to a page that has React running. Next, we incorrectly will try to mount React DevTools panels twice, which will result into conflicts in the Store, and the error will be shown to the user ## How did you test this change? Since this is a race condition, it is hard to reproduce consistently, but you can try this flow: 1. Open a page that is using React, open browser DevTools and React DevTools components panel 2. Open a page that is NOT using React, like google.com, wait ~5 seconds until you see `"Looks like this page doesn't have React, or it hasn't been loaded yet"` message in RDT panel 3. Open a page that is using React, observe the error `"Uncaught Error: Cannot add node "1" because a node with that id is already in the Store."` Couldn't been able to reproduce this with these changes.
This commit is contained in:
+10
-4
@@ -412,13 +412,19 @@ chrome.devtools.network.onNavigated.addListener(syncSavedPreferences);
|
||||
// into subscribing to the same events from Bridge and window multiple times
|
||||
// In this case, we will handle `operations` event twice or more and user will see
|
||||
// `Cannot add node "1" because a node with that id is already in the Store.`
|
||||
const debouncedOnNavigatedListener = debounce(() => {
|
||||
const debouncedMountReactDevToolsCallback = debounce(
|
||||
mountReactDevToolsWhenReactHasLoaded,
|
||||
500,
|
||||
);
|
||||
|
||||
// Clean up everything, but start mounting React DevTools panels if user stays at this page
|
||||
function onNavigatedToOtherPage() {
|
||||
performInTabNavigationCleanup();
|
||||
mountReactDevToolsWhenReactHasLoaded();
|
||||
}, 500);
|
||||
debouncedMountReactDevToolsCallback();
|
||||
}
|
||||
|
||||
// Cleanup previous page state and remount everything
|
||||
chrome.devtools.network.onNavigated.addListener(debouncedOnNavigatedListener);
|
||||
chrome.devtools.network.onNavigated.addListener(onNavigatedToOtherPage);
|
||||
|
||||
// Should be emitted when browser DevTools are closed
|
||||
if (__IS_FIREFOX__) {
|
||||
|
||||
Reference in New Issue
Block a user