fix(ui): toast auto-dismiss id derived inside the state updater (React 18 batching)

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
feat/client-detail-redesign
Thomas Joise 5 days ago
parent 03402ba0e1
commit 4e2b71cf9f

@ -1,4 +1,4 @@
import { createContext, useCallback, useContext, useMemo, useRef, useState, type ReactNode } from 'react'
import { createContext, useCallback, useContext, useMemo, useState, type ReactNode } from 'react'
import { dismissToast, initialToasts, pushToast, type Toast, type ToastState } from './toast-store'
const AUTO_DISMISS_MS = 4000
@ -9,13 +9,14 @@ const Ctx = createContext<ToastApi | null>(null)
/** Mount once at app root; renders the bottom-right stack. */
export function ToastProvider(props: { children: ReactNode }) {
const [state, setState] = useState<ToastState>(initialToasts)
const stateRef = useRef(state)
stateRef.current = state
const push = useCallback((tone: Toast['tone'], message: string) => {
const id = stateRef.current.nextId
setState((s) => pushToast(s, tone, message))
window.setTimeout(() => setState((s) => dismissToast(s, id)), AUTO_DISMISS_MS)
setState((s) => {
const next = pushToast(s, tone, message)
const id = next.toasts[next.toasts.length - 1]!.id
window.setTimeout(() => setState((s2) => dismissToast(s2, id)), AUTO_DISMISS_MS)
return next
})
}, [])
const api = useMemo<ToastApi>(() => ({

Loading…
Cancel
Save