Skip to content

chore: re-arm set-state-in-effect and close out the debt cleanup - #15

Merged
nimkimi merged 2 commits into
mainfrom
chore/rearm-set-state-in-effect
Aug 6, 2026
Merged

nimkimi merged 2 commits into
mainfrom
chore/rearm-set-state-in-effect

Conversation

@nimkimi

@nimkimi nimkimi commented Aug 6, 2026 •

Copy link
Copy Markdown
Owner

Why

Closes the post-upgrade debt cleanup. react-hooks/set-state-in-effect became an error in eslint-config-next 16 and was demoted to a warning to land the upgrade, with the six offending components tracked as follow-up. All six are now fixed at the pattern level rather than silenced, across #10–#14:

  • Reveal and MagneticButton read media queries through a shared useSyncExternalStore hook
  • Preloader's reduced-motion skip path no longer sets state synchronously in its layout effect
  • Toast and ContactClient derive the toast from the action state
  • SiteNav closes the mobile menu during render on a pathname change

What changed

Deleted the override block and its comment, restoring eslint-config-next 16's default. No other change.

Verification

npm run lint reports 0 errors and 0 warnings. npx tsc --noEmit is clean, npm test is 308 passed / 31 files, and npm run check passes.

The rule is armed, not merely un-overridden: a deliberate setState inside a useEffect added to a scratch component fails as 1 problem (1 error, 0 warnings) with react-hooks/set-state-in-effect. Probe removed before committing.

Also closes the feature

Ticks every acceptance criterion in docs/features/post-upgrade-debt-cleanup.md with its evidence, and moves the feature to the Done table in docs/ROADMAP.md.

Two screenshot differences are recorded under the spec's "or every difference is explained" clause. The original contact-page baseline turned out not to be reproducible — it was captured with a reCAPTCHA site key in the environment and no .env file exists in the repo, so contact rendered the real widget then and "reCAPTCHA is not configured." now. The comparison was re-based on a fresh same-environment capture of pre-change main, against which contact is byte-identical at both viewports. The other difference is the two reduced-motion first-paint shots, which changed on purpose.

No hydration warnings on a production build, checked in a real browser across all five routes at both prefers-reduced-motion settings — no console error or warning of any kind.

The rule was demoted to a warning to land the Next.js 16 upgrade, with the
six offending components tracked as follow-up work. All six are now fixed at
the pattern level rather than silenced: the media-query reads go through a
shared useSyncExternalStore hook, the arrival skip path no longer sets state
synchronously in its layout effect, the contact toast is derived from the
action state, and the nav closes on route change during render.

Deleting the override restores eslint-config-next 16's default. npm run lint
reports 0 errors and 0 warnings, and a deliberate setState-in-effect now
fails the build as an error rather than a warning.
@vercel

vercel Bot commented Aug 6, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
hackimi Ready Ready Preview Aug 6, 2026 2:39pm

Ticks every acceptance criterion with the evidence behind it, records the two
screenshot differences the spec's 'or every difference is explained' clause
allows, and moves the feature to the Done table in the roadmap.

The two explained differences: the original contact-page baseline is not
reproducible because it was captured with a reCAPTCHA site key in the
environment and no .env file exists in the repo, so the comparison was re-based
on a fresh same-environment capture of pre-change main; and the two
reduced-motion first-paint shots changed on purpose, which is the arrival fix.
@nimkimi nimkimi changed the title chore: restore react-hooks/set-state-in-effect to error chore: re-arm set-state-in-effect and close out the debt cleanup Aug 6, 2026
@nimkimi
nimkimi merged commit a65fcfb into main Aug 6, 2026
4 checks passed
@nimkimi
nimkimi deleted the chore/rearm-set-state-in-effect branch August 6, 2026 14:41

This branch was successfully deployed

1 active deployment
Preview — 46f5832b Deployed Aug 6, 2026 by vercel[bot]
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.

1 participant