Skip to content

Commit 3d9fb35

Browse files
authored
fix(eslint): fix react-hooks/refs issues (#7618)
1 parent ebb3c99 commit 3d9fb35

File tree

50 files changed

+388
-300
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

50 files changed

+388
-300
lines changed

configs/eslint-config-compass/index.js

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ const chaiFriendly = require('eslint-plugin-chai-friendly');
77

88
// TODO(COMPASS-9459): disabling a bunch of new rules to unblock automatic updates
99
const tempNewEslintRulesDisabled = {
10-
'react-hooks/refs': 'off',
1110
'react-hooks/preserve-manual-memoization': 'off',
1211
'@typescript-eslint/no-unsafe-enum-comparison': 'off',
1312
};

package-lock.json

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/compass-aggregations/src/components/pipeline-builder-workspace/pipeline-as-text-workspace/pipeline-editor.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {
99
useDarkMode,
1010
cx,
1111
useRequiredURLSearchParams,
12+
useCurrentValueRef,
1213
} from '@mongodb-js/compass-components';
1314
import {
1415
createAggregationAutocompleter,
@@ -83,8 +84,7 @@ export const PipelineEditor: React.FunctionComponent<PipelineEditorProps> = ({
8384
const track = useTelemetry();
8485
const connectionInfoRef = useConnectionInfoRef();
8586
const editorInitialValueRef = useRef<string>(pipelineText);
86-
const editorCurrentValueRef = useRef<string>(pipelineText);
87-
editorCurrentValueRef.current = pipelineText;
87+
const editorCurrentValueRef = useCurrentValueRef<string>(pipelineText);
8888

8989
const { utmSource, utmMedium } = useRequiredURLSearchParams();
9090

@@ -112,7 +112,7 @@ export const PipelineEditor: React.FunctionComponent<PipelineEditorProps> = ({
112112
);
113113
editorInitialValueRef.current = editorCurrentValueRef.current;
114114
}
115-
}, [num_stages, track, connectionInfoRef]);
115+
}, [editorCurrentValueRef, track, num_stages, connectionInfoRef]);
116116

117117
const annotations: Annotation[] = useMemo(() => {
118118
return syntaxErrors

packages/compass-aggregations/src/components/stage-editor/stage-editor.tsx

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import {
1414
Banner,
1515
useDarkMode,
1616
useRequiredURLSearchParams,
17+
useCurrentValueRef,
1718
} from '@mongodb-js/compass-components';
1819
import {
1920
changeStageValue,
@@ -99,8 +100,7 @@ export const StageEditor = ({
99100
const connectionInfoRef = useConnectionInfoRef();
100101
const darkMode = useDarkMode();
101102
const editorInitialValueRef = useRef<string | null>(stageValue);
102-
const editorCurrentValueRef = useRef<string | null>(stageValue);
103-
editorCurrentValueRef.current = stageValue;
103+
const editorCurrentValueRef = useCurrentValueRef<string | null>(stageValue);
104104

105105
const fields = useAutocompleteFields(namespace);
106106

@@ -150,6 +150,7 @@ export const StageEditor = ({
150150
editorInitialValueRef.current = editorCurrentValueRef.current;
151151
}
152152
}, [
153+
editorCurrentValueRef,
153154
track,
154155
num_stages,
155156
index,

packages/compass-app-registry/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@
5050
"reformat": "npm run eslint . -- --fix && npm run prettier -- --write ."
5151
},
5252
"dependencies": {
53+
"@mongodb-js/compass-components": "^1.56.0",
5354
"eventemitter3": "^4.0.0",
5455
"react": "^17.0.2",
5556
"react-redux": "^8.1.3",

packages/compass-app-registry/src/react-context.tsx

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,5 @@
1-
import React, {
2-
createContext,
3-
useEffect,
4-
useRef,
5-
useContext,
6-
useState,
7-
} from 'react';
1+
import React, { createContext, useEffect, useContext, useState } from 'react';
2+
import { useInitialValue } from '@mongodb-js/compass-components';
83
import { globalAppRegistry, AppRegistry } from './app-registry';
94

105
/**
@@ -57,7 +52,7 @@ export function GlobalAppRegistryProvider({
5752
value?: AppRegistry;
5853
children?: React.ReactNode;
5954
}) {
60-
const appRegistry = useRef(value ?? globalAppRegistry).current;
55+
const appRegistry = useInitialValue(value ?? globalAppRegistry);
6156
return (
6257
<GlobalAppRegistryContext.Provider value={appRegistry}>
6358
{children}
@@ -73,11 +68,11 @@ export function AppRegistryProvider({
7368
children,
7469
...props
7570
}: AppRegistryProviderProps) {
76-
const initialPropsRef = useRef(props);
71+
const initialProps = useInitialValue(props);
7772
const {
7873
localAppRegistry: initialLocalAppRegistry,
7974
deactivateOnUnmount = true,
80-
} = initialPropsRef.current;
75+
} = initialProps;
8176

8277
const globalAppRegistry = useGlobalAppRegistry();
8378
const isTopLevelProvider = useIsTopLevelProvider();

packages/compass-app-registry/src/register-plugin.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -92,7 +92,7 @@ function LegacyRefluxProvider({
9292
}) {
9393
const storeRef = useRef(store);
9494
const [state, setState] = useState(() => {
95-
return storeRef.current.state;
95+
return store.state;
9696
});
9797

9898
React.useEffect(() => {

packages/compass-assistant/src/compass-assistant-provider.tsx

Lines changed: 56 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@ import {
1212
atlasServiceLocator,
1313
} from '@mongodb-js/atlas-service/provider';
1414
import { DocsProviderTransport } from './docs-provider-transport';
15-
import { useDrawerActions } from '@mongodb-js/compass-components';
15+
import {
16+
useDrawerActions,
17+
useInitialValue,
18+
} from '@mongodb-js/compass-components';
1619
import {
1720
buildConnectionErrorPrompt,
1821
buildExplainPlanPrompt,
@@ -180,56 +183,12 @@ export const AssistantProvider: React.FunctionComponent<
180183
const { openDrawer } = useDrawerActions();
181184
const track = useTelemetry();
182185

183-
const createEntryPointHandler = useRef(function <T>(
184-
entryPointName:
185-
| 'explain plan'
186-
| 'performance insights'
187-
| 'connection error',
188-
builder: (props: T) => EntryPointMessage
189-
) {
190-
return (props: T) => {
191-
if (!assistantActionsContext.current.ensureOptInAndSend) {
192-
return;
193-
}
194-
195-
const { prompt, metadata } = builder(props);
196-
void assistantActionsContext.current.ensureOptInAndSend(
197-
{
198-
text: prompt,
199-
metadata: {
200-
...metadata,
201-
source: entryPointName,
202-
},
203-
},
204-
{},
205-
() => {
206-
openDrawer(ASSISTANT_DRAWER_ID);
207-
208-
track('Assistant Entry Point Used', {
209-
source: entryPointName,
210-
});
211-
}
212-
);
213-
};
214-
}).current;
215-
const assistantActionsContext = useRef<AssistantActionsContextType>({
216-
interpretExplainPlan: createEntryPointHandler(
217-
'explain plan',
218-
buildExplainPlanPrompt
219-
),
220-
interpretConnectionError: createEntryPointHandler(
221-
'connection error',
222-
buildConnectionErrorPrompt
223-
),
224-
tellMoreAboutInsight: createEntryPointHandler(
225-
'performance insights',
226-
buildProactiveInsightsPrompt
227-
),
228-
ensureOptInAndSend: async (
186+
const ensureOptInAndSend = useInitialValue(() => {
187+
return async function (
229188
message: SendMessage,
230189
options: SendOptions,
231190
callback: () => void
232-
) => {
191+
) {
233192
try {
234193
await atlasAiService.ensureAiFeatureAccess();
235194
} catch {
@@ -246,12 +205,59 @@ export const AssistantProvider: React.FunctionComponent<
246205
}
247206

248207
await chat.sendMessage(message, options);
249-
},
208+
};
209+
});
210+
211+
const createEntryPointHandler = useInitialValue(() => {
212+
return function <T>(
213+
entryPointName:
214+
| 'explain plan'
215+
| 'performance insights'
216+
| 'connection error',
217+
builder: (props: T) => EntryPointMessage
218+
) {
219+
return function (props: T) {
220+
const { prompt, metadata } = builder(props);
221+
void ensureOptInAndSend(
222+
{
223+
text: prompt,
224+
metadata: {
225+
...metadata,
226+
source: entryPointName,
227+
},
228+
},
229+
{},
230+
() => {
231+
openDrawer(ASSISTANT_DRAWER_ID);
232+
233+
track('Assistant Entry Point Used', {
234+
source: entryPointName,
235+
});
236+
}
237+
);
238+
};
239+
};
240+
});
241+
242+
const assistantActionsContext = useInitialValue<AssistantActionsContextType>({
243+
interpretExplainPlan: createEntryPointHandler(
244+
'explain plan',
245+
buildExplainPlanPrompt
246+
),
247+
interpretConnectionError: createEntryPointHandler(
248+
'connection error',
249+
buildConnectionErrorPrompt
250+
),
251+
tellMoreAboutInsight: createEntryPointHandler(
252+
'performance insights',
253+
buildProactiveInsightsPrompt
254+
),
255+
ensureOptInAndSend,
250256
});
251257

252258
return (
253259
<AssistantContext.Provider value={chat}>
254-
<AssistantActionsContext.Provider value={assistantActionsContext.current}>
260+
<AssistantActionsContext.Provider value={assistantActionsContext}>
255261
{children}
256262
</AssistantActionsContext.Provider>
257263
</AssistantContext.Provider>

packages/compass-collection/src/components/collection-tab-provider.tsx

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,8 @@
1-
import React, { useContext, useRef } from 'react';
1+
import React, { useContext } from 'react';
22
import type { CollectionTabPluginMetadata } from '../modules/collection-tab';
33
import type { CompassPluginComponent } from '@mongodb-js/compass-app-registry';
44
import type { CollectionSubtab } from '@mongodb-js/compass-workspaces';
5+
import { useInitialValue } from '@mongodb-js/compass-components';
56

67
export interface CollectionTabPlugin {
78
name: CollectionSubtab;
@@ -28,9 +29,9 @@ const CollectionTabComponentsContext =
2829
export const CollectionTabsProvider: React.FunctionComponent<
2930
Partial<CollectionTabComponentsProviderValue>
3031
> = ({ children, ...props }) => {
31-
const valueRef = useRef({ ...defaultComponents, ...props });
32+
const valueRef = useInitialValue({ ...defaultComponents, ...props });
3233
return (
33-
<CollectionTabComponentsContext.Provider value={valueRef.current}>
34+
<CollectionTabComponentsContext.Provider value={valueRef}>
3435
{children}
3536
</CollectionTabComponentsContext.Provider>
3637
);

packages/compass-components/src/components/accordion.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
1-
import React, { useCallback, useRef, useState } from 'react';
1+
import React, { useCallback, useState } from 'react';
22
import { spacing } from '@leafygreen-ui/tokens';
33
import { css, cx } from '@leafygreen-ui/emotion';
44
import { palette } from '@leafygreen-ui/palette';
55
import { useId } from '@react-aria/utils';
66
import { useDarkMode } from '../hooks/use-theme';
77

88
import { Description, Icon } from './leafygreen';
9+
import { useCurrentValueRef } from '../hooks/use-current-value-ref';
910

1011
const buttonStyles = css({
1112
fontWeight: 'bold',
@@ -94,15 +95,14 @@ function Accordion({
9495
}: React.PropsWithChildren<AccordionProps>): React.ReactElement {
9596
const darkMode = useDarkMode();
9697
const [localOpen, setLocalOpen] = useState(_open ?? defaultOpen);
97-
const setOpenRef = useRef(_setOpen);
98-
setOpenRef.current = _setOpen;
98+
const setOpenRef = useCurrentValueRef(_setOpen);
9999
const onOpenChange = useCallback(() => {
100100
setLocalOpen((prevValue) => {
101101
const newValue = !prevValue;
102102
setOpenRef.current?.(newValue);
103103
return newValue;
104104
});
105-
}, []);
105+
}, [setOpenRef]);
106106
const regionId = useId();
107107
const labelId = useId();
108108
const open = typeof _open !== 'undefined' ? _open : localOpen;

0 commit comments

Comments
 (0)