The ApproveAndSendDialog had a useEffect whose deps array included
`openNonce` — a state counter the effect itself incremented:
useEffect(() => {
if (!open) return;
setOpenNonce((n) => n + 1); // updates openNonce
// ... seed defaults ...
}, [open, openNonce, ...]); // openNonce is in deps
This produced Maximum update depth exceeded: the effect fires → state
updates → deps change → effect re-fires → loop, until React pulls the
plug.
The intent was 'seed once per open cycle, not on every claimerName /
repEmail update' (so async lookups arriving after the modal opened
didn't clobber operator edits). The state-counter approach was the
wrong mechanism for that — mutating a dep from inside the effect
*is* the loop.
Fix: replace openNonce (state) with seededFor (ref). A ref mutation
doesn't trigger re-render, so the loop is impossible. We still depend
on [open, quote.id] in the effect, and the ref's purpose is purely
'has this (open, quote.id) cycle been seeded yet?'. Reset to null on
open=false so the next open seeds fresh.
Dropped claimerName / repEmail from the deps too — they were the
reason openNonce existed in the first place (don't re-seed when they
update), and the ref now enforces that without the side-effect trap.
Tests: 229/230 vitest (the 1 failure is the pre-existing attachments
off-by-one, unrelated to this change).