Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 1 addition & 6 deletions packages/react-devtools-extensions/src/main/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -167,10 +167,6 @@ function createBridgeAndStore() {
supportsClickToInspect: true,
});

store.addListener('enableSuspenseTab', () => {
createSuspensePanel();
});

store.addListener('settingsUpdated', (hookSettings, componentFilters) => {
chrome.storage.local.set({...hookSettings, componentFilters});
});
Expand Down Expand Up @@ -565,8 +561,7 @@ function mountReactDevTools() {
createProfilerPanel();
createSourcesEditorPanel();
createElementsInspectPanel();
// Suspense Tab is created via the hook
// TODO(enableSuspenseTab): Create eagerly once Suspense tab is stable
createSuspensePanel();
}

let reactPollingInstance = null;
Expand Down
12 changes: 1 addition & 11 deletions packages/react-devtools-shared/src/backend/agent.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ import type {
ElementType,
} from 'react-devtools-shared/src/frontend/types';
import type {GroupItem} from './views/TraceUpdates/canvas';
import {gte, isReactNativeEnvironment} from './utils';
import {isReactNativeEnvironment} from './utils';
import {
sessionStorageGetItem,
sessionStorageRemoveItem,
Expand Down Expand Up @@ -961,16 +961,6 @@ export default class Agent extends EventEmitter<{

rendererInterface.setTraceUpdatesEnabled(this._traceUpdatesEnabled);

const renderer = rendererInterface.renderer;
if (renderer !== null) {
const devRenderer = renderer.bundleType === 1;
const enableSuspenseTab =
devRenderer && gte(renderer.version, '19.3.0-canary');
if (enableSuspenseTab) {
this._bridge.send('enableSuspenseTab');
}
}

// When the renderer is attached, we need to tell it whether
// we remember the previous selection that we'd like to restore.
// It'll start tracking mounts for matches to the last selection path.
Expand Down
1 change: 0 additions & 1 deletion packages/react-devtools-shared/src/bridge.js
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,6 @@ export type BackendEvents = {
backendInitialized: [],
backendVersion: [string],
bridgeProtocol: [BridgeProtocol],
enableSuspenseTab: [],
extensionBackendInitialized: [],
fastRefreshScheduled: [],
getSavedPreferences: [],
Expand Down
13 changes: 0 additions & 13 deletions packages/react-devtools-shared/src/devtools/store.js
Original file line number Diff line number Diff line change
Expand Up @@ -143,7 +143,6 @@ export default class Store extends EventEmitter<{
backendVersion: [],
collapseNodesByDefault: [],
componentFilters: [],
enableSuspenseTab: [],
error: [Error],
hookSettings: [$ReadOnly<DevToolsHookSettings>],
hostInstanceSelected: [Element['id'] | null],
Expand Down Expand Up @@ -239,8 +238,6 @@ export default class Store extends EventEmitter<{
_supportsClickToInspect: boolean = false;
_supportsTimeline: boolean = false;
_supportsTraceUpdates: boolean = false;
// Dynamically set if the renderer supports the Suspense tab.
_supportsSuspenseTab: boolean = false;

_isReloadAndProfileFrontendSupported: boolean = false;
_isReloadAndProfileBackendSupported: boolean = false;
Expand Down Expand Up @@ -341,7 +338,6 @@ export default class Store extends EventEmitter<{
bridge.addListener('hookSettings', this.onHookSettings);
bridge.addListener('backendInitialized', this.onBackendInitialized);
bridge.addListener('selectElement', this.onHostInstanceSelected);
bridge.addListener('enableSuspenseTab', this.onEnableSuspenseTab);
}

// This is only used in tests to avoid memory leaks.
Expand Down Expand Up @@ -2394,15 +2390,6 @@ export default class Store extends EventEmitter<{
}
}

get supportsSuspenseTab(): boolean {
return this._supportsSuspenseTab;
}

onEnableSuspenseTab = (): void => {
this._supportsSuspenseTab = true;
this.emit('enableSuspenseTab');
};

// The Store should never throw an Error without also emitting an event.
// Otherwise Store errors will be invisible to users,
// but the downstream errors they cause will be reported as bugs.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import {
UNKNOWN_SUSPENDERS_REASON_OLD_VERSION,
UNKNOWN_SUSPENDERS_REASON_THROWN_PROMISE,
} from '../../../constants';
import {ElementTypeRoot} from 'react-devtools-shared/src/frontend/types';

type RowProps = {
bridge: FrontendBridge,
Expand Down Expand Up @@ -477,7 +478,21 @@ export default function InspectedElementSuspendedBy({
</div>
);
}
return null;
// For roots, show an empty state since there's nothing else to show for
// these elements.
// This can happen for older versions of React without Suspense, older versions
// of React with less sources for Suspense, or simple UIs that don't have any suspenders.
if (inspectedElement.type === ElementTypeRoot) {
return (
<div>
<div className={styles.HeaderRow}>
<div className={`${styles.Header} ${styles.Empty}`}>
Nothing suspended the initial paint.
</div>
</div>
</div>
);
}
}

const handleCopy = withPermissionsCheck(
Expand Down
38 changes: 10 additions & 28 deletions packages/react-devtools-shared/src/devtools/views/DevTools.js
Original file line number Diff line number Diff line change
Expand Up @@ -135,21 +135,7 @@ const suspenseTab = {
title: 'React Suspense',
};

const defaultTabs = [componentsTab, profilerTab];
const tabsWithSuspense = [componentsTab, profilerTab, suspenseTab];

function useIsSuspenseTabEnabled(store: Store): boolean {
const subscribe = useCallback(
(onStoreChange: () => void) => {
store.addListener('enableSuspenseTab', onStoreChange);
return () => {
store.removeListener('enableSuspenseTab', onStoreChange);
};
},
[store],
);
return React.useSyncExternalStore(subscribe, () => store.supportsSuspenseTab);
}
const tabs = [componentsTab, profilerTab, suspenseTab];

export default function DevTools({
bridge,
Expand Down Expand Up @@ -183,8 +169,6 @@ export default function DevTools({
LOCAL_STORAGE_DEFAULT_TAB_KEY,
defaultTab,
);
const enableSuspenseTab = useIsSuspenseTabEnabled(store);
const tabs = enableSuspenseTab ? tabsWithSuspense : defaultTabs;

let tab = currentTab;

Expand Down Expand Up @@ -364,17 +348,15 @@ export default function DevTools({
}
/>
</div>
{enableSuspenseTab && (
<div
className={styles.TabContent}
hidden={tab !== 'suspense'}>
<SuspenseTab
portalContainer={
suspensePortalContainer
}
/>
</div>
)}
<div
className={styles.TabContent}
hidden={tab !== 'suspense'}>
<SuspenseTab
portalContainer={
suspensePortalContainer
}
/>
</div>
</div>
{editorPortalContainer ? (
<EditorPane
Expand Down
Loading