From 3dc9b5852f5e6face60473df6c6f649730c4721f Mon Sep 17 00:00:00 2001 From: Randall Stillwell Date: Fri, 11 Sep 2026 13:07:30 -0500 Subject: [PATCH] fix(scanner): resolve stale closure in handleCardScanned - Add scannedCardsRef to track latest queue state - Use functional updater in setScannedCards to avoid stale mergeScannedCardEntry input - Return cardEntry.id synchronously from handleCardScanned so onScanImageUploaded fires This fixes the scanner queue stopping after 1 card (required page refresh to see more). --- lib/use-scanner-queue.js | 24 ++++++++++++++++-------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/lib/use-scanner-queue.js b/lib/use-scanner-queue.js index 173aea2..4128bcb 100644 --- a/lib/use-scanner-queue.js +++ b/lib/use-scanner-queue.js @@ -45,6 +45,11 @@ export function useScannerQueue({ user, sessionDestination, scanDefaults, deckMo const addingInFlightRef = useRef(new Set()); const [addingCardIds, setAddingCardIds] = useState(() => new Set()); const cartPersistTimerRef = useRef(null); + const scannedCardsRef = useRef(scannedCards); + + useEffect(() => { + scannedCardsRef.current = scannedCards; + }, [scannedCards]); const persistCart = (cards, selection) => { saveScannerCart({ @@ -162,22 +167,25 @@ export function useScannerQueue({ user, sessionDestination, scanDefaults, deckMo setUndoStack((prev) => prev.filter((u) => u.cardId !== cardId)); }, []); - const handleCardScanned = (cardData) => { + const handleCardScanned = useCallback((cardData) => { setAutoRouteError(null); const { cardEntry, scannedCards: nextQueue } = mergeScannedCardEntry( - scannedCards, + scannedCardsRef.current, cardData, scanDefaults ); - setScannedCards(nextQueue); - setSelectedCards((prev) => { - const next = new Set([...prev, cardEntry.id]); - persistCart(nextQueue, next); - return next; + setScannedCards((prev) => { + const { cardEntry: ce, scannedCards: nq } = mergeScannedCardEntry(prev, cardData, scanDefaults); + setSelectedCards((ps) => { + const n = new Set([...ps, ce.id]); + persistCart(nq, n); + return n; + }); + return nq; }); return cardEntry.id; - }; + }, [scanDefaults]); const incrementCardQuantity = (cardId) => { setScannedCards((prev) =>