fix(vocal): stabilize the event handlers to prevent listener leaks on re-render #111
fix(vocal): stabilize the event handlers to prevent listener leaks on re-render #111Muneebkhnnn wants to merge 1 commit intountemps:mainfrom
Conversation
- Memoize handlers with the useCallback - Stabilize handler map with useMemo - Ensure subscribe/unsubscribe use same function references - Prevent duplicate listeners during active session
|
Hi @Muneebkhnnn, thanks for the thorough analysis — the problem you identified is real. A quick heads-up though: main is being superseded by v2.0.0, currently in pre-release on the beta branch. That branch already includes a significant rewrite of Vocal.js (React 19 migration, propTypes removal, simplified event handling), so this patch doesn't apply cleanly there. The stale prop callback issue still exists in beta. Two options:
What's your preference? Does the urgency justify a v1.x patch? |
|
PR #112 covers the full scope of yours, targeting beta (the upcoming v2.0.0) rather than main. It applies the same core approach — useCallback on all handlers, useMemo on HANDLERS, propsRef for stable prop callbacks, onEndRef/stableTimerCb to break the circular dep — with two corrections over your implementation: unsubscribeAllRef is assigned inline during render instead of in a useEffect (avoids a first-mount timing gap), and |
|
Thanks! So should I keep #111 open for the v1.7.x patch on main, or would you prefer to close it? |
|
Thanks @Muneebkhnnn! I'll close this in favour of the work already underway on the upcoming major release — the fix will ship as part of v2.0.0. |
Problem
Event handlers in
Vocal.jsxwere recreated on every render.Since subscribe/unsubscribe rely on reference equality, this caused
mismatches when a re-render occurred during an active recognition session,
leading to potential listener leaks.
Solution
useCallbackuseMemouseVocal,useTimeoutand
useCommandshooks (stop,triggerCommand,on*prop callbacks)Testing