Skip to content

Commit 6086b2b

Browse files
committed
[DevTools] Wrap each tab in <Activity> if available
1 parent 19f65ff commit 6086b2b

File tree

2 files changed

+135
-92
lines changed

2 files changed

+135
-92
lines changed

packages/react-devtools-shared/src/devtools/views/DevTools.js

Lines changed: 134 additions & 91 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,14 @@ import '@reach/menu-button/styles.css';
1313
import '@reach/tooltip/styles.css';
1414

1515
import * as React from 'react';
16-
import {useCallback, useEffect, useLayoutEffect, useMemo, useRef} from 'react';
16+
import {
17+
StrictMode,
18+
useCallback,
19+
useEffect,
20+
useLayoutEffect,
21+
useMemo,
22+
useRef,
23+
} from 'react';
1724
import Store from '../store';
1825
import {
1926
BridgeContext,
@@ -56,6 +63,37 @@ import type {BrowserTheme} from 'react-devtools-shared/src/frontend/types';
5663
import type {ReactFunctionLocation, ReactCallSite} from 'shared/ReactTypes';
5764
import type {SourceSelection} from './Editor/EditorPane';
5865

66+
const MaybeActivity =
67+
React.unstable_Activity ||
68+
function AlwaysVisibleActivity({
69+
children,
70+
}: {
71+
children: React.Node,
72+
mode: string,
73+
}) {
74+
return children;
75+
};
76+
77+
function TabContent({
78+
children,
79+
activeTab,
80+
name,
81+
}: {
82+
children: React.Node,
83+
activeTab: string,
84+
name: string,
85+
}) {
86+
const hidden = activeTab !== name;
87+
const mode = hidden ? 'hidden' : 'visible';
88+
return (
89+
<MaybeActivity mode={mode} name={name + '-tab'}>
90+
<div className={styles.TabContent} hidden={hidden}>
91+
{children}
92+
</div>
93+
</MaybeActivity>
94+
);
95+
}
96+
5997
export type TabID = 'components' | 'profiler' | 'suspense';
6098

6199
export type ViewElementSource = (
@@ -289,6 +327,7 @@ export default function DevTools({
289327
useLayoutEffect(() => {
290328
return () => {
291329
try {
330+
// TODO: <DevTools> can't be put int <Activity> without being able to resume listening
292331
// Shut the Bridge down synchronously (during unmount).
293332
bridge.shutdown();
294333
} catch (error) {
@@ -302,98 +341,102 @@ export default function DevTools({
302341
}, []);
303342

304343
return (
305-
<BridgeContext.Provider value={bridge}>
306-
<StoreContext.Provider value={store}>
307-
<OptionsContext.Provider value={options}>
308-
<ContextMenuContext.Provider value={contextMenu}>
309-
<ModalDialogContextController>
310-
<SettingsContextController
311-
browserTheme={browserTheme}
312-
componentsPortalContainer={componentsPortalContainer}
313-
profilerPortalContainer={profilerPortalContainer}>
314-
<ViewElementSourceContext.Provider value={viewElementSource}>
315-
<HookNamesModuleLoaderContext.Provider
316-
value={hookNamesModuleLoaderFunction || null}>
317-
<FetchFileWithCachingContext.Provider
318-
value={fetchFileWithCaching || null}>
319-
<TreeContextController>
320-
<ProfilerContextController>
321-
<TimelineContextController>
322-
<InspectedElementContextController>
323-
<SuspenseTreeContextController>
324-
<ThemeProvider>
325-
<div
326-
className={styles.DevTools}
327-
ref={devToolsRef}
328-
data-react-devtools-portal-root={true}>
329-
{showTabBar && (
330-
<div className={styles.TabBar}>
331-
<ReactLogo />
332-
<span
333-
className={styles.DevToolsVersion}>
334-
{process.env.DEVTOOLS_VERSION}
335-
</span>
336-
<div className={styles.Spacer} />
337-
<TabBar
338-
currentTab={tab}
339-
id="DevTools"
340-
selectTab={selectTab}
341-
tabs={tabs}
342-
type="navigation"
343-
/>
344-
</div>
345-
)}
346-
<div
347-
className={styles.TabContent}
348-
hidden={tab !== 'components'}>
349-
<Components
350-
portalContainer={
351-
componentsPortalContainer
352-
}
353-
/>
354-
</div>
344+
<StrictMode>
345+
<BridgeContext.Provider value={bridge}>
346+
<StoreContext.Provider value={store}>
347+
<OptionsContext.Provider value={options}>
348+
<ContextMenuContext.Provider value={contextMenu}>
349+
<ModalDialogContextController>
350+
<SettingsContextController
351+
browserTheme={browserTheme}
352+
componentsPortalContainer={componentsPortalContainer}
353+
profilerPortalContainer={profilerPortalContainer}>
354+
<ViewElementSourceContext.Provider value={viewElementSource}>
355+
<HookNamesModuleLoaderContext.Provider
356+
value={hookNamesModuleLoaderFunction || null}>
357+
<FetchFileWithCachingContext.Provider
358+
value={fetchFileWithCaching || null}>
359+
<TreeContextController>
360+
<ProfilerContextController>
361+
<TimelineContextController>
362+
<InspectedElementContextController>
363+
<SuspenseTreeContextController>
364+
<ThemeProvider>
355365
<div
356-
className={styles.TabContent}
357-
hidden={tab !== 'profiler'}>
358-
<Profiler
359-
portalContainer={
360-
profilerPortalContainer
361-
}
362-
/>
366+
className={styles.DevTools}
367+
ref={devToolsRef}
368+
data-react-devtools-portal-root={true}>
369+
{showTabBar && (
370+
<div className={styles.TabBar}>
371+
<ReactLogo />
372+
<span
373+
className={styles.DevToolsVersion}>
374+
{process.env.DEVTOOLS_VERSION}
375+
</span>
376+
<div className={styles.Spacer} />
377+
<TabBar
378+
currentTab={tab}
379+
id="DevTools"
380+
selectTab={selectTab}
381+
tabs={tabs}
382+
type="navigation"
383+
/>
384+
</div>
385+
)}
386+
<TabContent
387+
name="components"
388+
activeTab={tab}>
389+
<Components
390+
portalContainer={
391+
componentsPortalContainer
392+
}
393+
/>
394+
</TabContent>
395+
<TabContent
396+
name="profiler"
397+
activeTab={tab}>
398+
<Profiler
399+
portalContainer={
400+
profilerPortalContainer
401+
}
402+
/>
403+
</TabContent>
404+
<TabContent
405+
name="suspense"
406+
activeTab={tab}>
407+
<SuspenseTab
408+
portalContainer={
409+
suspensePortalContainer
410+
}
411+
/>
412+
</TabContent>
363413
</div>
364-
<div
365-
className={styles.TabContent}
366-
hidden={tab !== 'suspense'}>
367-
<SuspenseTab
368-
portalContainer={
369-
suspensePortalContainer
370-
}
414+
{editorPortalContainer ? (
415+
<EditorPane
416+
selectedSource={currentSelectedSource}
417+
portalContainer={editorPortalContainer}
371418
/>
372-
</div>
373-
</div>
374-
{editorPortalContainer ? (
375-
<EditorPane
376-
selectedSource={currentSelectedSource}
377-
portalContainer={editorPortalContainer}
378-
/>
379-
) : null}
380-
</ThemeProvider>
381-
</SuspenseTreeContextController>
382-
</InspectedElementContextController>
383-
</TimelineContextController>
384-
</ProfilerContextController>
385-
</TreeContextController>
386-
</FetchFileWithCachingContext.Provider>
387-
</HookNamesModuleLoaderContext.Provider>
388-
</ViewElementSourceContext.Provider>
389-
</SettingsContextController>
390-
<UnsupportedBridgeProtocolDialog />
391-
{warnIfLegacyBackendDetected && <WarnIfLegacyBackendDetected />}
392-
{warnIfUnsupportedVersionDetected && <UnsupportedVersionDialog />}
393-
</ModalDialogContextController>
394-
</ContextMenuContext.Provider>
395-
</OptionsContext.Provider>
396-
</StoreContext.Provider>
397-
</BridgeContext.Provider>
419+
) : null}
420+
</ThemeProvider>
421+
</SuspenseTreeContextController>
422+
</InspectedElementContextController>
423+
</TimelineContextController>
424+
</ProfilerContextController>
425+
</TreeContextController>
426+
</FetchFileWithCachingContext.Provider>
427+
</HookNamesModuleLoaderContext.Provider>
428+
</ViewElementSourceContext.Provider>
429+
</SettingsContextController>
430+
<UnsupportedBridgeProtocolDialog />
431+
{warnIfLegacyBackendDetected && <WarnIfLegacyBackendDetected />}
432+
{warnIfUnsupportedVersionDetected && (
433+
<UnsupportedVersionDialog />
434+
)}
435+
</ModalDialogContextController>
436+
</ContextMenuContext.Provider>
437+
</OptionsContext.Provider>
438+
</StoreContext.Provider>
439+
</BridgeContext.Provider>
440+
</StrictMode>
398441
);
399442
}

packages/react-devtools-shell/src/app/InspectableElements/UseEffectEvent.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@ function useCustomHook() {
2828
}
2929

3030
function HookTreeCase() {
31-
const onClick = useCustomHook();
31+
const [, , onClick] = useCustomHook();
3232

3333
return <div onClick={onClick} />;
3434
}

0 commit comments

Comments
 (0)