I have the following React provider:
import { createContext, useCallback, useContext, useEffect, useRef, useState } from 'react';
export const AlertContext = createContext({
addAlert: () => {},
alerts: [],
clearAlert: () => {},
setAlerts: () => {},
});
export function useAlert() {
return useContext(AlertContext);
}
export function AlertProvider(props: { children: React.ReactNode }) {
const [alerts, setAlerts] = useState([]);
const clearAlert = useCallback(
(idToRemove: string | null) => {
// Clear a specific alert by ID.
if (idToRemove) {
setAlerts(alerts => alerts.filter(a => a.id !== idToRemove));
return;
}
},
[],
);
const addAlert = useCallback(
(alert: any, options?: { autoDismissTime?: number }) => {
setAlerts(alerts => {
if (options?.autoDismissTime) {
setTimeout(() => {
clearAlert(alert.id);
}, options.autoDismissTime)
}
return [...alerts, alert];
});
},
[clearAlert],
);
return (
<AlertContext.Provider value={{ alerts, setAlerts, addAlert, clearAlert }}>
{props.children}
<ClientOnly>
{() => <AlertContainer alerts={alerts} clearAlert={clearAlert} />}
</ClientOnly>
</AlertContext.Provider>
);
}
And then in one of my components I do this:
const { addAlert } = useAlert();
// Add the alert
addAlert(...)
I would like to know what is the proper way to ensure that I don't leave any timeouts hanging in that provider (how should I manage the clearTimeout). I have seen examples on how to unset a specific timer in a component when it unmounts, but in this case I can have multiple timeouts (as many as alerts are being set with an autoDismissTime)
At the start of the component:
Then:
And then cleanup: