From 5de23e1988d2c2be15a095d5baddb754401c35ca Mon Sep 17 00:00:00 2001 From: Drew Davis Date: Thu, 9 Apr 2026 15:08:23 -0400 Subject: [PATCH] fix: Restore some react-hook lint rules (#2084) ## Summary This PR: - Updates the eslint config to restore `react-hook` plugin rules which were removed in #2069. Some of them were removed in without any replacements being _enabled_ in the recommended @eslint-react ruleset - Reverts #2074, as those lint fixes were possible only because the related rules had been removed Rule equivalence is documented here: https://www.eslint-react.xyz/docs/migrating-from-eslint-plugin-react-hooks You can view current effective rule states with `cd packages/app && npx eslint --inspect-config` ### How to test locally or on Vercel Locally: ``` make ci-lint / make dev-lint ``` ### References - Linear Issue: HDX-3467 - Related PRs: --- packages/app/eslint.config.mjs | 22 ++++++++++++++++--- packages/app/src/DBChartPage.tsx | 1 + packages/app/src/DOMPlayer.tsx | 1 + .../app/src/components/DBHeatmapChart.tsx | 2 +- .../src/components/SQLEditor/SQLEditor.tsx | 2 +- .../components/SQLEditor/SQLInlineEditor.tsx | 1 + packages/app/src/hooks/useResizable.tsx | 2 +- packages/app/src/hooks/useStableCallback.ts | 2 +- packages/app/src/timeQuery.ts | 4 +++- packages/app/src/useQueryParam.tsx | 1 + packages/app/src/utils.ts | 2 +- 11 files changed, 31 insertions(+), 9 deletions(-) diff --git a/packages/app/eslint.config.mjs b/packages/app/eslint.config.mjs index aa9b4b43..d02587a5 100644 --- a/packages/app/eslint.config.mjs +++ b/packages/app/eslint.config.mjs @@ -122,12 +122,28 @@ export default [ ...nextPlugin.configs.recommended.rules, ...nextPlugin.configs['core-web-vitals'].rules, ...reactHooksPlugin.configs.recommended.rules, - ...eslintReactPlugin.configs.recommended.rules, - // Disable rules from eslint-plugin-react-hooks that have equivalent rules in @eslint-react - ...eslintReactPlugin.configs['disable-conflict-eslint-plugin-react-hooks'].rules, ...eslintReactPlugin.configs['recommended-type-checked'].rules, + + // Non-default react-hooks rules + 'react-hooks/set-state-in-render': 'error', 'react-hooks/set-state-in-effect': 'warn', 'react-hooks/exhaustive-deps': 'error', + + // Disable rules from @eslint-react that have equivalent rules enabled in eslint-plugin-react-hooks + '@eslint-react/rules-of-hooks': 'off', + '@eslint-react/component-hook-factories': 'off', + '@eslint-react/exhaustive-deps': 'off', + '@eslint-react/error-boundaries': 'off', + '@eslint-react/immutability': 'off', + '@eslint-react/purity': 'off', + '@eslint-react/refs': 'off', + '@eslint-react/set-state-in-effect': 'off', + '@eslint-react/set-state-in-render': 'off', + '@eslint-react/no-nested-component-definitions': 'off', + '@eslint-react/no-nested-lazy-component-declarations': 'off', + '@eslint-react/unsupported-syntax': 'off', + '@eslint-react/use-memo': 'off', + 'react-hook-form/no-use-watch': 'error', '@eslint-react/no-unstable-default-props': 'error', '@typescript-eslint/ban-ts-comment': 'warn', diff --git a/packages/app/src/DBChartPage.tsx b/packages/app/src/DBChartPage.tsx index b77c7602..82f2e5e2 100644 --- a/packages/app/src/DBChartPage.tsx +++ b/packages/app/src/DBChartPage.tsx @@ -166,6 +166,7 @@ function AIAssistant({ {opened && ( + // eslint-disable-next-line react-hooks/refs
{ document.removeEventListener('mousemove', handleResize); - + // eslint-disable-next-line react-hooks/immutability document.removeEventListener('mouseup', endResize); }, [handleResize]); diff --git a/packages/app/src/hooks/useStableCallback.ts b/packages/app/src/hooks/useStableCallback.ts index fc978fad..2ca50d1b 100644 --- a/packages/app/src/hooks/useStableCallback.ts +++ b/packages/app/src/hooks/useStableCallback.ts @@ -10,7 +10,7 @@ export const useStableCallback = any>( }); return useCallback( - // eslint-disable-next-line @typescript-eslint/no-unsafe-type-assertion + // eslint-disable-next-line react-hooks/use-memo, @typescript-eslint/no-unsafe-type-assertion ((...args: Parameters) => callbackRef.current(...args)) as T, [], ); diff --git a/packages/app/src/timeQuery.ts b/packages/app/src/timeQuery.ts index f8f24f3d..175fa351 100644 --- a/packages/app/src/timeQuery.ts +++ b/packages/app/src/timeQuery.ts @@ -243,12 +243,13 @@ export function useTimeQuery({ liveTailTimeRange == null && tempLiveTailTimeRange == null && !isInputTimeQueryLive(inputTimeQuery) && + // eslint-disable-next-line react-hooks/refs inputTimeQueryDerivedTimeQueryRef.current != null ) { // Use the input time query, allows users to specify relative time ranges // via url ex. /logs?tq=Last+30+minutes // return inputTimeQueryDerivedTimeQuery as [Date, Date]; - + // eslint-disable-next-line react-hooks/refs return inputTimeQueryDerivedTimeQueryRef.current; } else if ( isReady && @@ -344,6 +345,7 @@ export function useTimeQuery({ ], ); + // eslint-disable-next-line react-hooks/refs return { isReady, // Don't search until we know what we want to do isLive, diff --git a/packages/app/src/useQueryParam.tsx b/packages/app/src/useQueryParam.tsx index 0f4f3ef7..56840865 100644 --- a/packages/app/src/useQueryParam.tsx +++ b/packages/app/src/useQueryParam.tsx @@ -28,6 +28,7 @@ export const QueryParamProvider = ({ const setState = useCallback( (state: Record) => { + // eslint-disable-next-line react-hooks/immutability setCache(oldCache => { const newCache = { ...oldCache, diff --git a/packages/app/src/utils.ts b/packages/app/src/utils.ts index 1aa0b572..e20b5b1d 100644 --- a/packages/app/src/utils.ts +++ b/packages/app/src/utils.ts @@ -643,7 +643,7 @@ export const usePrevious = (value: T): T | undefined => { useEffect(() => { ref.current = value; }); - + // eslint-disable-next-line react-hooks/refs return ref.current; };