chore(web): upgrade eslint-plugin-react-hooks to 7.1.x + fix flagged smells#8
Merged
Conversation
…d smells Bumps the override from 7.0.1 (pinned in PR #7 to dodge the new rules) to 7.1.1, which activates the React Compiler lint rules (purity, set-state-in-effect, refs, immutability), and resolves the 12 violations they surface. Kept as an explicit pin: this plugin adds CI-gating rules in minor releases (eslint-config-next only requests ^7.0.0), so deliberate bumps avoid surprise breakage. Real fixes (behavior-preserving): - useEventSource: write onEvent into the ref from an effect, not during render (refs rule). Only async SSE handlers read it, after commit. - useSessions: hoist the markUpdated useCallback above its first use (immutability rule) — declaration-order only. - ApiTokens/Users settings sections: move the mount fetch into a cancellable async IIFE so setState lands after the await (set-state-in-effect), keeping the try/finally so a rejected fetch can't strand the loading spinner. - EventLog: read the clock from an interval-refreshed `now` state instead of during render (purity). Strictly less churny than the prior per-render Date.now(); the time-window cutoff lags <=30s. Scoped, justified eslint-disables for genuine false positives: terminating derived-state resets (setPage(0), setSelectedIndex(0)) and intentional point-in-time pause snapshots in EventLog. Verification: web lint 0/0, full build green, 1166 tests pass, clean npm ci. An adversarial 4-lens review caught the stranded-spinner error path, now fixed. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Completes the deferred follow-up from #7: it pinned
eslint-plugin-react-hooksto 7.0.1 to dodge the new React Compiler lint rules. This bumps the override to 7.1.1, turns those rules on, and fixes the 12 violations they flag.The rules now active:
react-hooks/purity(no clock/impure reads in render),react-hooks/set-state-in-effect(no synchronous setState in effects),react-hooks/refs(no ref writes during render),react-hooks/immutability(no use-before-declare).The override is kept as an explicit pin rather than removed: this plugin ships new CI-gating lint rules in minor releases, and
[email protected]only requests^7.0.0— so a deliberate pin protects CI from a surprise float to 7.2.x.Real fixes (behavior-preserving)
hooks/useEventSource.tsonEventinto the ref from auseEffect, not during render. Only async SSE handlers read it, strictly after commit.hooks/useSessions.tsmarkUpdateduseCallbackabove its first use — declaration-order only; deps/body/call-site byte-for-byte unchanged.settings/ApiTokensSection.tsx,settings/UsersSection.tsxsetStatelands after theawait. Kept thetry/finallyso a rejected fetch / throwingres.json()can't strand the loading spinner.events/EventLog.tsxnowstate instead ofDate.now()during render. Strictly less churny than the prior per-render read (thesinceparam isn't forwarded to the SSE stream, so no reconnect thrash); time-window cutoff lags ≤30s.Scoped eslint-disables (genuine false positives)
Terminating derived-state resets (
setPage(0),setSelectedIndex(0)in AuditSection / CommandPalette) and intentional point-in-time pause snapshots in EventLog. Each has a justifying comment.Verification
npm run buildgreen (all packages incl. Next build)npm ci(lock ↔ package.json consistent; 45 Linux optional deps preserved for Linux CI)try/finallyin the inlined mount fetch), now fixed; the other 3 lenses confirmed the diff is behavior-preserving.🤖 Generated with Claude Code