import React , { useContext , useState , createContext , useMemo , useCallback } from 'react' ; import useTimeout from './useTimeout' ; export type Toast = { identifier : string ; status : string ; message : string ; secondaryMessage ? : string ; } ; const ToastContext = createContext < { toasts ? : Toast [ ] ; setToasts ? : React . Dispatch < React . SetStateAction < Toast [ ] > > ; } > ( { } ) ; param { Object } props return export const ToastProvider = props => { const [ toasts , setToasts ] = useState < Toast [ ] > ( [ ] ) ; const value = useMemo ( ( ) => ( { toasts , setToasts } ) , [ toasts , setToasts ] ) ; return < ToastContext . Provider value = { value } { ... props } />; } ; return { Object } export const useToast = ( ) => { const context = useContext ( ToastContext ) ; if ( ! context ) { throw new Error ( 'useToast must be used within a DataProvider.' ) ; } const { addTimeout } = useTimeout ( ) ; const { toasts : toastsOpt , setToasts } = context ; const toasts = toastsOpt ! ; const closeToast = useCallback ( ( targetedIdentifier ) => ( ) => { setToasts ! ( toasts => { const updatedToasts = [ ... toasts ] ; const index = updatedToasts . findIndex ( ( { identifier } ) => identifier === targetedIdentifier ) ; updatedToasts . splice ( index , 1 ) ; return updatedToasts ; } ) ; } , [ setToasts ] ) ; const openToast = useCallback ( ( identifier , status , message , secondaryMessage ? , timeout = 5000 ) => { const timeoutId = setTimeout ( closeToast ( identifier ) , timeout ) ; closeToast ( identifier ) ( ) ; setToasts ! ( toasts => [ ... toasts , { identifier , status , message , secondaryMessage } ] ) ; addTimeout ( timeoutId ) ; } , [ addTimeout , closeToast , setToasts ] ) ; const updateToast = useCallback ( ( targetedIdentifier , status , message , secondaryMessage ? , timeout = 5000 ) => { setToasts ! ( toasts => { const updatedToasts = [ ... toasts ] ; const index = updatedToasts . findIndex ( ( { identifier } ) => identifier === targetedIdentifier ) ; if ( index !== - 1 ) { updatedToasts . splice ( index , 1 ) ; } return [ ... updatedToasts , { identifier : targetedIdentifier , status , message , secondaryMessage } ] ; } ) ; const timeoutId = setTimeout ( closeToast ( targetedIdentifier ) , timeout ) ; addTimeout ( timeoutId ) ; } , [ addTimeout , closeToast , setToasts ] ) ; return { toasts , openToast , updateToast , closeToast } ; } ;