Skip to content

Suppress react-hooks/refs in LiveAircraftMap so main's deploy chain runs again - #685

Merged
jehanazad merged 1 commit into
mainfrom
fix/react-hooks-refs-lint
Oct 29, 2026
Merged

jehanazad merged 1 commit into
mainfrom
fix/react-hooks-refs-lint

Conversation

@jehanazad

Copy link
Copy Markdown
Contributor

Why

Since #670 bumped eslint-plugin-react-hooks 7.0.1 → 7.1.1, every push to main has failed the Web (dashboard checks) job at npm run lint -w dashboard (example: run 39088109488). ci.yml's Staging job needs that gate, so the Staging and Production deploy chain was skipped for #670, #661 and #684. #684 was deployed to staging by hand on 2026-10-18; production has had none of the three.

What

All 49 errors are the stricter react-hooks/refs rule firing in one file, dashboard/src/pages/map/LiveAircraftMap.tsx. That component deliberately keeps the live feed in refs (fixes, smoothed positions, trails, playback history, marker registry), mutated at 60 fps by the animation loop and on every ingest, and re-renders on explicit ticks that read the stores as they stand. The rule assumes the React Compiler, which this app does not use, and it follows derived values: selectedTrail, history and friends get flagged at every later use, so per-line suppressions would reopen with each new use.

  • LiveAircraftMap.tsx: /* eslint-disable react-hooks/refs -- … */ at the top of the file, with the reasoning in the comment. No code change.
  • The rule stays on in eslint.config.js for every other file, where it already passes. (The config already switches off the sibling compiler rules purity, immutability and rules-of-hooks-unsafe-access globally; this stays narrower than that.)
  • Not touched: the 5 react-hooks/set-state-in-effect warnings in DashboardLayout.tsx, LiveAircraftMap.tsx, PhysicsSettings.tsx, map/hooks.ts and ResultsTree.tsx. The config scores that rule as a warning and they do not fail the job.

Moving the stores into state or useSyncExternalStore would be a redesign of the map's hot path and belongs in its own change.

Verified locally (node:24-alpine, as CI)

  • npm run lint -w dashboard: 0 errors, 5 warnings (was 49 / 5)
  • npm run typecheck -w dashboard: pass
  • npm test -w dashboard: pass
  • npm run build -w dashboard: pass

🤖 Generated with Claude Code

…uns again

eslint-plugin-react-hooks 7.1.1 (npm group bump, #670) tightened the
`refs` rule: it now reports every read of `ref.current` during render and
every value derived from one. LiveAircraftMap keeps the live feed in refs
by design (fixes, smoothed positions, trails, playback history, the marker
registry, all mutated at 60 fps by the animation loop and on each ingest,
with React re-rendering on explicit ticks), so the rule reported 49
errors there and nowhere else. The web-build gate has been red since, and
ci.yml's Staging job needs that gate, so #670, #661 and #684 all skipped
the staging and production deploys; #684 was deployed by hand.

The rule is turned off for this one file, with the reasoning in the
header. Per-line suppressions would not hold, because the rule follows
derived values (selectedTrail, history) into every later use. Moving the
stores into state or useSyncExternalStore is a redesign of the map's hot
path and out of scope for unblocking deploys. The rule stays on for every
other file, where it already passes. The five remaining
set-state-in-effect warnings are untouched; the config scores them as
warnings and they do not fail the job.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
@claude

claude Bot commented Oct 19, 2026 •

Copy link
Copy Markdown

Claude finished @jehanazad's task in 1m 48s —— View job


Claude's review

  • Gather context (PR diff, changed files, repo instructions)
  • Review the lint-suppression change in LiveAircraftMap.tsx
  • Check CLAUDE.md / ONBOARDING for relevant repo rules
  • Post review feedback

Summary

The diff is exactly what the PR description says: 11 added lines, all a single /* eslint-disable react-hooks/refs -- ... */ block comment at the very top of dashboard/src/pages/map/LiveAircraftMap.tsx, before any imports. No behavioral code changes.

Verification

  • eslint.config.js confirms the claims in the PR body: react-hooks/refs comes from reactHooks.configs.recommended.rules (not explicitly listed), while the sibling compiler rules purity, rules-of-hooks-unsafe-access and immutability are already turned off globally — this PR stays narrower than that by only suppressing one rule in one file.
  • package.json / package-lock.json confirm eslint-plugin-react-hooks is pinned to ^7.1.1, matching the version bump blamed for the regression.
  • ci.yml confirms the gating chain: the Staging job (needs: [..., lint, ...]) depends on the Web (dashboard checks) job, so a lint failure there does skip Staging/Production — consistent with the "deploy chain was skipped for Bump the npm group across 1 directory with 9 updates #670, Windows compatibility: /dev/tcp port check, guard resource import #661, Bind the known lane on staging, one step ahead of production #684" claim.
  • Live CI on this PR (run 39186336145) shows Web (dashboard checks): success, and the full matrix green — empirically confirming the fix resolves the lint failure (I did not have node_modules installed locely to re-run npm run lint -w dashboard myself, so this CI result is the verification).
  • A second, unrelated file (AvailabilityTimeline.tsx) mentions react-hooks/refs only in an explanatory comment about avoiding a ref — it's not an additional error site, so the "all 49 errors are in one file" claim holds.

Assessment

This is a minimal, well-justified, low-risk lint suppression:

  • Placement at the top of the file (before imports) is correct for a file-scoped ESLint disable directive.
  • The suppression is scoped to one rule in one file rather than globally, and the comment explains why (refs mutated at 60fps outside the React Compiler model, with per-line suppression being unworkable because the rule follows derived values).
  • It doesn't touch .github/workflows, doesn't touch the node API contract or backend/uv.lock, and doesn't introduce new dependencies — none of the other CLAUDE.md gates (just contract, relocking, etc.) apply here.
  • No functional/runtime change, so no risk to the map's behavior.

No issues found. This looks safe to merge as-is.

@jehanazad
jehanazad merged commit 9e33e7b into main Oct 29, 2026
18 checks passed
@jehanazad
jehanazad deleted the fix/react-hooks-refs-lint branch October 29, 2026 03:19
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants