From c6e09869d1a01128755a6823f0b02a5af1cc5c89 Mon Sep 17 00:00:00 2001 From: Carlos Feria <2582866+carlosthe19916@users.noreply.github.com> Date: Wed, 27 May 2026 12:50:10 +0200 Subject: [PATCH] chore(eslint): enable @eslint-react/use-state rule Use lazy initial state for useState calls that involve function calls or object construction to prevent re-computation on every render. Co-Authored-By: Claude Opus 4.6 (1M context) --- client/src/app/hooks/usePersistentState.ts | 1 + client/src/app/hooks/useSelectionState.ts | 2 +- client/src/app/hooks/useStorage.ts | 2 +- client/src/app/pages/home/watched-sboms-provider.tsx | 2 +- client/src/app/pages/sbom-groups/sbom-groups-provider.tsx | 2 +- eslint.config.mjs | 1 - 6 files changed, 5 insertions(+), 5 deletions(-) diff --git a/client/src/app/hooks/usePersistentState.ts b/client/src/app/hooks/usePersistentState.ts index 84d949d5a..4be272b71 100644 --- a/client/src/app/hooks/usePersistentState.ts +++ b/client/src/app/hooks/usePersistentState.ts @@ -80,6 +80,7 @@ export const usePersistentState = < persistenceKeyPrefix ? `${persistenceKeyPrefix}:${key}` : key; const persistence = { + // eslint-disable-next-line @eslint-react/use-state -- intentionally stored as tuple in persistence map state: React.useState(defaultValue), urlParams: useUrlParams( isUrlParamsOptions(options) diff --git a/client/src/app/hooks/useSelectionState.ts b/client/src/app/hooks/useSelectionState.ts index 44cf890ff..d6895a473 100644 --- a/client/src/app/hooks/useSelectionState.ts +++ b/client/src/app/hooks/useSelectionState.ts @@ -30,7 +30,7 @@ export const useSelectionState = ({ initialSelected = [], isEqual = (a, b) => a === b, }: ISelectionStateArgs): ISelectionState => { - const [selectedSet, setSelectedSet] = React.useState( + const [selectedSet, setSelectedSet] = React.useState(() => doSelect(isEqual, items, initialSelected), ); diff --git a/client/src/app/hooks/useStorage.ts b/client/src/app/hooks/useStorage.ts index fcac903bd..9e815db2c 100644 --- a/client/src/app/hooks/useStorage.ts +++ b/client/src/app/hooks/useStorage.ts @@ -60,7 +60,7 @@ const useStorage = ({ key, defaultValue, }: IUseStorageOptions): [T, React.Dispatch>] => { - const [cachedValue, setCachedValue] = React.useState( + const [cachedValue, setCachedValue] = React.useState(() => getValueFromStorage(type, key, defaultValue), ); diff --git a/client/src/app/pages/home/watched-sboms-provider.tsx b/client/src/app/pages/home/watched-sboms-provider.tsx index 2806cfe9e..ce66ed304 100644 --- a/client/src/app/pages/home/watched-sboms-provider.tsx +++ b/client/src/app/pages/home/watched-sboms-provider.tsx @@ -20,7 +20,7 @@ export const WatchedSbomsProvider: React.FunctionComponent< > = ({ children }) => { const { pushNotification } = React.useContext(NotificationsContext); const [mutatingKeys, setMutatingKeys] = React.useState>( - new Set(), + () => new Set(), ); const { sboms, isFetching, fetchError } = useFetchWatchedSboms(); diff --git a/client/src/app/pages/sbom-groups/sbom-groups-provider.tsx b/client/src/app/pages/sbom-groups/sbom-groups-provider.tsx index d3e42637b..1f3898b54 100644 --- a/client/src/app/pages/sbom-groups/sbom-groups-provider.tsx +++ b/client/src/app/pages/sbom-groups/sbom-groups-provider.tsx @@ -49,7 +49,7 @@ export const SbomGroupsProvider: React.FunctionComponent< // Track manually expanded node IDs (browse mode only) const [expandedNodeIds, setExpandedNodeIds] = React.useState>( - new Set(), + () => new Set(), ); const toggleExpandedNodes = React.useCallback((node: SbomGroupItem) => { diff --git a/eslint.config.mjs b/eslint.config.mjs index 37cf5f34d..d740e6b70 100644 --- a/eslint.config.mjs +++ b/eslint.config.mjs @@ -39,7 +39,6 @@ export default defineConfig([ "@eslint-react/rules-of-hooks": "off", "@eslint-react/naming-convention-ref-name": "off", "@eslint-react/no-array-index-key": "off", - "@eslint-react/use-state": "off", "@eslint-react/no-unnecessary-use-prefix": "off", "@typescript-eslint/no-unused-vars": "off", "@eslint-react/static-components": "off",