我有以下 React 提供程序:
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>
);
}
然后在我的一个组件中我这样做:
const { addAlert } = useAlert();
// Add the alert
addAlert(...)
我想知道什么是确保我不会在该提供程序中留下任何超时的正确方法(我应该如何管理
clearTimeout
)。我看过有关如何在组件卸载时取消设置组件中的特定计时器的示例,但在这种情况下,我可以有多个超时(使用 autoDismissTime
设置的警报数量一样多)
在组件的开头:
const timeoutsRef = useRef<Record<number, number>>([])
然后:
const id = setTimeout(() => {
clearAlert(alert.id);
delete timeoutsRef.current[alert.id]
}, options.autoDismissTime)
timeoutsRef.current[alert.id] = id
然后清理:
useEffect(() => {
return () => {
Object.values(timeoutsRef.current).forEach((id) => {
clearTimeout(id)
})
}
}, [])