mirror of
https://github.com/harvard-edge/cs249r_book.git
synced 2026-07-16 14:42:29 -05:00
[PR #1912] [MERGED] fix(staffml): keep practice-page Cmd+Enter handler fresh via latest-callback refs #36527
Reference in New Issue
Block a user
Delete Branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
📋 Pull Request Information
Original PR: https://github.com/harvard-edge/cs249r_book/pull/1912
Author: @farhan523
Created: 6/28/2026
Status: ✅ Merged
Merged: 7/10/2026
Merged by: @profvjreddi
Base:
dev← Head:fix/practice-stale-userAnswer📝 Commits (1)
9ea0c6afix(staffml): keep practice-page Cmd+Enter handler fresh via latest-callback refs📊 Changes
1 file changed (+28 additions, -3 deletions)
View changed files
📝
interviews/staffml/src/app/practice/page.tsx(+28 -3)📄 Description
Summary
The global keyboard listener in
practice/page.tsxis intentionally stable — re-armed only whenshowAnswer/current/pickRandomchange so it doesn't churn on every keystroke. But the handlers it calls close over state that DOES change between listener re-arms:Bug 1 (the one that surfaces visibly): stale
userAnswerhandleReveal(line 460+) closes overuserAnswer.setUserAnswerre-renders → freshhandleRevealexists in the new render, but the keydown effect's deps ([showAnswer, current, pickRandom]) didn't change so the effect doesn't re-run.handleRevealwhich closes over the OLDuserAnswer(empty string).charsTyped = userAnswer.trim().length = 0→ think-guard at line 466 misfires the "are you sure?" modal AFTER the user has actually deliberated.Bug 2 (same class, smaller blast radius): stale
effectiveMaxScorehandleScore(line 545+) closes overeffectiveMaxScore(derived fromrubricItems/napkinResult).showAnswer=truere-arms the listener) → ticks rubric checkboxes →effectiveMaxScorechanges → digit-key listener still calls the stalehandleScorethat caps the score at the OLD max.The Reveal/score buttons at lines 1190/1361/1397/1489 are unaffected — they invoke a fresh closure on click.
Fix
Latest-callback ref pattern (same shape as
useVisibilityPollfrom #1834):Inline comment in both spots documents the trap so a future "cleanup" doesn't undo it.
Test plan
npx vitest run→ 126/126 across 22 files passing (unchanged fromdev; no new tests added — see Notes).npx tsc --noEmit→ clean./practice. Wait for a question to load.🔄 This issue represents a GitHub Pull Request. It cannot be merged through Gitea due to API limitations.