Skip to content

Commit 6fe1bbe

Browse files
authored
fix(eslint): resolve react-hooks/globals react-hooks/immutability issues (#7612)
1 parent f9c90f3 commit 6fe1bbe

File tree

8 files changed

+50
-12
lines changed

8 files changed

+50
-12
lines changed

configs/eslint-config-compass/index.js

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,9 @@ 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/immutability': 'off',
1110
'react-hooks/refs': 'off',
1211
'react-hooks/set-state-in-effect': 'off',
1312
'react-hooks/preserve-manual-memoization': 'off',
14-
'react-hooks/globals': 'off',
1513
'react-hooks/static-components': 'off',
1614
'@typescript-eslint/no-redundant-type-constituents': 'off',
1715
'@typescript-eslint/no-unsafe-enum-comparison': 'off',

configs/testing-library-compass/src/index.tsx

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -340,8 +340,13 @@ function createWrapper(
340340
const StoreGetter: React.FunctionComponent = ({ children }) => {
341341
const store = useStore();
342342
const actions = useConnectionActions();
343-
wrapperState.connectionsStore.getState = store.getState.bind(store);
344-
wrapperState.connectionsStore.actions = actions;
343+
// We're breaking the rules of hooks on purpose here to expose the values
344+
// outside of the render for testing purposes
345+
// eslint-disable-next-line react-hooks/immutability
346+
Object.assign(wrapperState.connectionsStore, {
347+
getState: store.getState.bind(store),
348+
actions,
349+
});
345350
return <>{children}</>;
346351
};
347352
const logger = {
@@ -618,6 +623,9 @@ function createPluginWrapper<
618623
) {
619624
const ref: { current: PluginContext } = { current: {} as any };
620625
function ComponentWithProvider({ children, ...props }: any) {
626+
// We're breaking the rules of hooks on purpose here to expose the ref
627+
// outside of the render
628+
// eslint-disable-next-line react-hooks/immutability
621629
const plugin = (ref.current = Plugin.useActivate(
622630
initialPluginProps ?? ({} as any)
623631
));

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,6 +120,10 @@ export const ClearChatButton: React.FunctionComponent<{
120120
if (confirmed) {
121121
await stop();
122122
clearError();
123+
// Instead of breaking React rules, we should probably expose the "clear"
124+
// as an interface on the chat class. Otherwise it's kinda expected taht
125+
// we "mutate" messages directly to update the state
126+
// eslint-disable-next-line react-hooks/immutability
123127
chat.messages = chat.messages.filter(
124128
(message) => message.metadata?.isPermanent
125129
);

packages/compass-components/src/components/drawer-portal.spec.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ describe('DrawerSection', function () {
2121

2222
function TestDrawer() {
2323
const [count, _setCount] = useState(0);
24+
// Exposed for testing purposes
25+
// eslint-disable-next-line react-hooks/globals
2426
setCount = _setCount;
2527
return (
2628
<DrawerContentProvider>

packages/compass-components/src/components/drawer-portal.tsx

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,9 @@ type DrawerActionsContextValue = {
5151
closeDrawer: () => void;
5252
updateToolbarData: (data: DrawerSectionProps) => void;
5353
removeToolbarData: (id: string) => void;
54+
setCurrent: (
55+
fn: (current: DrawerActionsContextValue['current']) => void
56+
) => void;
5457
};
5558
};
5659

@@ -78,6 +81,7 @@ const DrawerActionsContext = React.createContext<DrawerActionsContextValue>({
7881
closeDrawer: () => undefined,
7982
updateToolbarData: () => undefined,
8083
removeToolbarData: () => undefined,
84+
setCurrent: () => undefined,
8185
},
8286
});
8387

@@ -124,7 +128,7 @@ export const DrawerContentProvider: React.FunctionComponent<{
124128
useState<DrawerOpenStateContextValue>(false);
125129
const [drawerCurrentTab, setDrawerCurrentTab] =
126130
useState<DrawerCurrentTabStateContextValue>(null);
127-
const drawerActions = useRef({
131+
const drawerActions = useRef<DrawerActionsContextValue['current']>({
128132
openDrawer: () => undefined,
129133
closeDrawer: () => undefined,
130134
updateToolbarData: (data: DrawerSectionProps) => {
@@ -147,6 +151,9 @@ export const DrawerContentProvider: React.FunctionComponent<{
147151
});
148152
});
149153
},
154+
setCurrent: (fn) => {
155+
fn(drawerActions.current);
156+
},
150157
});
151158

152159
const prevDrawerCurrentTabRef = React.useRef<string | null>(null);
@@ -187,11 +194,14 @@ export const DrawerContentProvider: React.FunctionComponent<{
187194

188195
const DrawerContextGrabber: React.FunctionComponent = ({ children }) => {
189196
const drawerToolbarContext = useDrawerToolbarContext();
190-
const actions = useContext(DrawerActionsContext);
191197
const openStateSetter = useContext(DrawerSetOpenStateContext);
192198
const currentTabSetter = useContext(DrawerSetCurrentTabContext);
193-
actions.current.openDrawer = drawerToolbarContext.openDrawer;
194-
actions.current.closeDrawer = drawerToolbarContext.closeDrawer;
199+
const actions = useContext(DrawerActionsContext);
200+
201+
actions.current.setCurrent((current) => {
202+
current.openDrawer = drawerToolbarContext.openDrawer;
203+
current.closeDrawer = drawerToolbarContext.closeDrawer;
204+
});
195205

196206
useEffect(() => {
197207
openStateSetter(drawerToolbarContext.isDrawerOpen);

packages/compass-connections/src/hooks/connection-tab-theme-provider.spec.tsx

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ describe('ConnectionThemeProvider', function () {
3131
let capturedTheme: ReturnType<typeof useTabTheme> = undefined;
3232

3333
const TestComponent = () => {
34+
// Doing this to test the value
35+
// eslint-disable-next-line react-hooks/globals
3436
capturedTheme = useTabTheme();
3537
return null;
3638
};
@@ -53,6 +55,8 @@ describe('ConnectionThemeProvider', function () {
5355
let capturedTheme: ReturnType<typeof useTabTheme> = undefined;
5456

5557
const TestComponent = () => {
58+
// Doing this to test the value
59+
// eslint-disable-next-line react-hooks/globals
5660
capturedTheme = useTabTheme();
5761
return null;
5862
};
@@ -87,6 +91,8 @@ describe('ConnectionThemeProvider', function () {
8791
let capturedTheme: ReturnType<typeof useTabTheme> = undefined;
8892

8993
const TestComponent = () => {
94+
// Doing this to test the value
95+
// eslint-disable-next-line react-hooks/globals
9096
capturedTheme = useTabTheme();
9197
return null;
9298
};
@@ -119,6 +125,8 @@ describe('ConnectionThemeProvider', function () {
119125
};
120126

121127
const TestComponent = () => {
128+
// Doing this to test the value
129+
// eslint-disable-next-line react-hooks/globals
122130
capturedTheme = useTabTheme();
123131
return null;
124132
};
@@ -151,6 +159,8 @@ describe('ConnectionThemeProvider', function () {
151159
};
152160

153161
const TestComponent = () => {
162+
// Doing this to test the value
163+
// eslint-disable-next-line react-hooks/globals
154164
capturedTheme = useTabTheme();
155165
return <div>Theme consumer</div>;
156166
};

packages/compass-web/sandbox/sandbox-atlas-sign-in.tsx

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -78,7 +78,7 @@ export function useAtlasProxySignIn(): AtlasLoginReturnValue {
7878
null
7979
);
8080

81-
const signIn = ((window as any).__signIn = useCallback(async () => {
81+
const signIn = useCallback(async () => {
8282
try {
8383
const { projectId } = await fetch('/authenticate', {
8484
method: 'POST',
@@ -94,9 +94,9 @@ export function useAtlasProxySignIn(): AtlasLoginReturnValue {
9494
description: (err as any).message,
9595
});
9696
}
97-
}, []));
97+
}, []);
9898

99-
const signOut = ((window as any).__signOut = useCallback(() => {
99+
const signOut = useCallback(() => {
100100
return fetch('/logout').then(
101101
() => {
102102
window.location.reload();
@@ -105,7 +105,11 @@ export function useAtlasProxySignIn(): AtlasLoginReturnValue {
105105
// noop
106106
}
107107
);
108-
}, []));
108+
}, []);
109+
110+
// Global is modified only for local dev convenience
111+
// eslint-disable-next-line react-hooks/immutability
112+
Object.assign(window, { __signIn: signIn, __signOut: signOut });
109113

110114
useEffect(() => {
111115
let mounted = true;

packages/compass-workspaces/src/index.spec.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ describe('WorkspacesPlugin', function () {
6565

6666
async function renderPlugin() {
6767
function OpenWorkspaceFnsGetter() {
68+
// exposed outside of render loop for testing
69+
// eslint-disable-next-line react-hooks/globals
6870
openFns = useOpenWorkspace();
6971
return null;
7072
}

0 commit comments

Comments
 (0)