Skip to content

fix(auto-withdraw): eliminate stale closure in settings persistence - #411

Merged
Austinaminu2 merged 2 commits into
FlowwStar:mainfrom
brightfootlimited-collab:fix/issue-276-stale-closure-auto-withdraw
Jul 26, 2026
Merged

fix(auto-withdraw): eliminate stale closure in settings persistence#411
Austinaminu2 merged 2 commits into
FlowwStar:mainfrom
brightfootlimited-collab:fix/issue-276-stale-closure-auto-withdraw

Conversation

@brightfootlimited-collab

Copy link
Copy Markdown
Contributor

Problem updateSettings (and by extension calculateWithdrawAmount) captured the settings state value from their outer closure. Because React state updates are asynchronous, a settings change made between renders could be silently overwritten in localStorage when �ddWithdrawalHistory was called shortly after — no error, no warning, user changes just vanished. Reported in #276. ## Root cause s // Before — stale closure const updateSettings = useCallback((update) => { const next = { ...settings, ...update }; // 'settings' may be stale setSettings(next); saveSettings(stream.id, next); // writes the stale snapshot }, [stream, settings]); settings in the dep array means the callback is recreated on every render, but between a setState call and the next render the closed-over value is still the old one. ## Fix Three changes, all in hooks/use-auto-withdraw.ts: 1. Add settingsRef — a useRef kept in sync with state on every write. Gives all callbacks a live, synchronous view of settings without being a stale closure. 2. updateSettings → functional updater s const updateSettings = useCallback((update) => { setSettings((prev) => { const next = { ...prev, ...update }; // always current settingsRef.current = next; saveSettings(stream.id, next); return next; }); }, [stream]); // 'settings' dep removed 3. calculateWithdrawAmount → reads settingsRef.current Drops the [settings] dep array entirely, making the callback stable and never stale. �ddWithdrawalHistory already used the functional updater correctly; settingsRef.current = next was added to keep the ref in sync. ## Testing - Change a setting (e.g. toggle strategy), then trigger a withdrawal history entry before the next render — localStorage now reflects the latest setting, not the snapshot from the previous render. - calculateWithdrawAmount uses the live strategy/threshold values at the moment the interval fires, not the value captured when the interval was set up. Closes #276

…pdateSettings read from the closed-over settings snapshot rather than the current state, meaning a settings change made between renders could be silently overwritten in localStorage when a withdrawal history entry was added shortly after. Fix: - Add settingsRef (useRef) that is kept in sync with state on every write, giving all callbacks a live view of settings without adding them to dependency arrays. - Rewrite updateSettings to use the functional setSettings((prev) => ...) form so it merges from the actual current state, not a stale closure; remove the settings dep from its useCallback array. - �ddWithdrawalHistory already used the functional updater correctly; add settingsRef.current = next so the ref stays in sync here too. - Rewrite calculateWithdrawAmount to read from settingsRef.current at call time instead of capturing settings in a closure; drop the [settings] dependency entirely so the callback is stable. Closes FlowwStar#276
@drips-wave

drips-wave Bot commented Jul 26, 2026

Copy link
Copy Markdown

@brightfootlimited-collab Great news! 🎉 Based on an automated assessment of this PR, the linked Wave issue(s) no longer count against your application limits.

You can now already apply to more issues while waiting for a review of this PR. Keep up the great work! 🚀

Learn more about application limits

@Austinaminu2
Austinaminu2 merged commit e2e3a19 into FlowwStar:main Jul 26, 2026
0 of 6 checks passed
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.

bug: auto-withdraw settings save uses a stale closure and can silently revert user changes

2 participants