问题描述
const ToastContextProvider: React.FC = ({ children }) => {
const [toasts,setToasts] = useState<ToastDeFinition[]>([]);
const addToast = useCallback(
(toast: ToastDeFinition) => {
if (toasts.find(({ id }) => id === toast.id)) {
return logger.warn('Attempted to add a new toast with a duplicate ID!',{
toast,});
}
setToasts((toasts) => [...toasts,{ ...toast }]);
},[toasts]
);
const removetoast = (id: string) => {
setToasts((toasts) => toasts.filter((toast) => toast.id !== id));
};
const value = {
addToast,removetoast,};
return (
<ToastContext.Provider value={value}>
<ToastPortal toasts={toasts} />
{children}
</ToastContext.Provider>
);
};
这个想法是我会在一个组件中调用 addToast,其中 toast 是一个像这样的对象;
{
id: 'test',message: 'Hello world',}
如果 ID 存在于 toasts 状态中,则不允许使用。但是,在 addToast 中调用 console.log(toasts) 总是记录一个空数组,并且 arr.find() 检查总是返回 undefined as结果,允许添加重复的 toast。
ToastPortal 会收到更新后的状态值。
解决方法
将 addToast
添加到您的 useEffect
的依赖项数组,以便关闭当前 addToast
值的最新 toasts
函数参与您的间隔逻辑。一个空的依赖数组意味着在开始时创建的 addToast
被重复调用,并且该方法关闭了 toasts
的初始值 []
。
useEffect(() => {
const interval = setInterval(() => {
addToast({
id: "test",msg: "testmsg"
});
},5000);
return () => clearInterval(interval);
},[addToast]);