I have an Alert
component which is basically built with BlueprintJS Toast component:
<code>import { OverlayToaster, Intent, ToasterPosition } from "@blueprintjs/core";
import { useCallback, useEffect, useRef, useState } from "react";
import { useAppDispatch, useAppSelector } from "redux/hooks";
import actions from "redux/alert/actions";
function Alert() {
const alert = useAppSelector((state) => state.alert.alert);
const alertTimeout = useAppSelector((state) => state.settings.alertTimeout);
const [position, setPosition] = useState<ToasterPosition>("top-right");
// reference to blueprint toaster
const toaster = useRef<OverlayToaster>(null);
const getTimeout = useCallback(
(type: Intent) =>
type === "success" ? alertTimeout.success : alertTimeout.error,
[alertTimeout.success, alertTimeout.error]
);
// set alert to undefined after display
const dispatch = useAppDispatch();
const removeAlert = useCallback(
(isManuallyDimissed: boolean | undefined) => {
dispatch(actions.SET_STATE({ alert: undefined }));
if (isManuallyDimissed) {
toaster.current?.clear();
}
},
[dispatch, toaster]
);
useEffect(() => {
if (alert) {
setPosition(alert.position);
toaster.current?.show({
message: alert.message,
intent: alert.type,
timeout: alert.isManualDismiss ? 3000000 : getTimeout(alert.type),
onDismiss: () => removeAlert(alert.isManualDismiss),
});
}
}, [dispatch, alert, getTimeout, removeAlert]);
return <OverlayToaster position={position} ref={toaster} />;
}
export default Alert;
</code>
<code>import { OverlayToaster, Intent, ToasterPosition } from "@blueprintjs/core";
import { useCallback, useEffect, useRef, useState } from "react";
import { useAppDispatch, useAppSelector } from "redux/hooks";
import actions from "redux/alert/actions";
function Alert() {
const alert = useAppSelector((state) => state.alert.alert);
const alertTimeout = useAppSelector((state) => state.settings.alertTimeout);
const [position, setPosition] = useState<ToasterPosition>("top-right");
// reference to blueprint toaster
const toaster = useRef<OverlayToaster>(null);
const getTimeout = useCallback(
(type: Intent) =>
type === "success" ? alertTimeout.success : alertTimeout.error,
[alertTimeout.success, alertTimeout.error]
);
// set alert to undefined after display
const dispatch = useAppDispatch();
const removeAlert = useCallback(
(isManuallyDimissed: boolean | undefined) => {
dispatch(actions.SET_STATE({ alert: undefined }));
if (isManuallyDimissed) {
toaster.current?.clear();
}
},
[dispatch, toaster]
);
useEffect(() => {
if (alert) {
setPosition(alert.position);
toaster.current?.show({
message: alert.message,
intent: alert.type,
timeout: alert.isManualDismiss ? 3000000 : getTimeout(alert.type),
onDismiss: () => removeAlert(alert.isManualDismiss),
});
}
}, [dispatch, alert, getTimeout, removeAlert]);
return <OverlayToaster position={position} ref={toaster} />;
}
export default Alert;
</code>
import { OverlayToaster, Intent, ToasterPosition } from "@blueprintjs/core";
import { useCallback, useEffect, useRef, useState } from "react";
import { useAppDispatch, useAppSelector } from "redux/hooks";
import actions from "redux/alert/actions";
function Alert() {
const alert = useAppSelector((state) => state.alert.alert);
const alertTimeout = useAppSelector((state) => state.settings.alertTimeout);
const [position, setPosition] = useState<ToasterPosition>("top-right");
// reference to blueprint toaster
const toaster = useRef<OverlayToaster>(null);
const getTimeout = useCallback(
(type: Intent) =>
type === "success" ? alertTimeout.success : alertTimeout.error,
[alertTimeout.success, alertTimeout.error]
);
// set alert to undefined after display
const dispatch = useAppDispatch();
const removeAlert = useCallback(
(isManuallyDimissed: boolean | undefined) => {
dispatch(actions.SET_STATE({ alert: undefined }));
if (isManuallyDimissed) {
toaster.current?.clear();
}
},
[dispatch, toaster]
);
useEffect(() => {
if (alert) {
setPosition(alert.position);
toaster.current?.show({
message: alert.message,
intent: alert.type,
timeout: alert.isManualDismiss ? 3000000 : getTimeout(alert.type),
onDismiss: () => removeAlert(alert.isManualDismiss),
});
}
}, [dispatch, alert, getTimeout, removeAlert]);
return <OverlayToaster position={position} ref={toaster} />;
}
export default Alert;
I actually want to be able to dismiss all toast messages when I shift
+ dismiss one of the toasts. I havent found a way how to, so I decided to dismiss all the toasts onDismiss
when it is manually dismissed. However, when I try to execute toaster.current?.clear()
, I get a maximum call stack size exceeded
.