Open Elugormo opened 2 years ago
Hello!
Same issue here, did you find a solution by any chance?
You might try to set a unique Id to the toast, so this problem won't appear if multiple requests for the same operation are coming, as shown in my Sandbox. By setting { toastId: 'something' } you will omit the problem for obvious reasons - only one promise will be handled. But in case there are a lot of them and they are different, this is impossible due to the specifics of the mechanisms that are used inside the library. I haven't found a trivial solution to this one by inspecting the code.
@Elugormo Thanks for your answer, it's a bit helping although still an issue..
It appears to work ordinarily if you pass any updateId
on Promise
toast invocation (perhaps in conjunction with a toastId
), but this in turn will violate the limit
property, whereby each appearing Promise
toast will push the other toasts beyond that threshold.
I think it will help you.
I just customized toast for my project like this. (this is just simple component, so you need to re-customize component based on your project.)
import { Bounce, Id, ToastOptions, toast } from "react-toastify";
// Notification Utility
const toastIds: Record<string, Id> = {};
export const alert = (
label: string,
type: "info" | "success" | "warning" | "error" | "default" = "success",
mode: "light" | "dark" = "dark"
): void => {
if (toastIds[label] && toast.isActive(toastIds[label])) {
return;
}
const options: ToastOptions = {
position: "top-center",
autoClose: 5000,
hideProgressBar: false,
closeOnClick: true,
pauseOnHover: true,
draggable: true,
progress: undefined,
theme: mode,
transition: Bounce
};
const toastFunc = {
info: toast.info,
success: toast.success,
warning: toast.warn,
error: toast.error,
default: toast
};
toastIds[label] = toastFunc[type](label, options);
};
in this case, even if you click several times toast event, it will show only one toast. maybe it can be a way to solve this problem.
thanks
Or other way to keep 3 alert as like you wanted.
import React, { useState, useCallback } from "react";
import ReactDOM from "react-dom";
import { ToastContainer, toast } from "react-toastify";
import "react-toastify/dist/ReactToastify.css";
const App = () => {
const [queue, setQueue] = useState([]);
const limit = 3;
const addToQueue = (promise, resolve, reject) => {
setQueue((prevQueue) => [
...prevQueue,
{ promise, resolve, reject }
]);
};
const processQueue = useCallback(() => {
setQueue((prevQueue) => {
const activePromises = prevQueue.filter((item) => item.promise.status === 'pending');
const availableSlots = limit - activePromises.length;
if (availableSlots > 0) {
const nextPromises = prevQueue.filter((item) => item.promise.status === 'queued').slice(0, availableSlots);
nextPromises.forEach((item) => {
item.promise.status = 'pending';
item.promise
.then(() => {
item.resolve();
processQueue();
})
.catch(() => {
item.reject();
processQueue();
});
});
}
return prevQueue.filter((item) => item.promise.status !== 'resolved' && item.promise.status !== 'rejected');
});
}, [limit]);
const handleNotify = () => {
const promise = new Promise((resolve, reject) => {
addToQueue(promise, resolve, reject);
processQueue();
});
promise.status = 'queued';
toast.promise(
promise,
{
pending: "Promise is pending",
success: "Promise resolved",
error: "Promise rejected"
}
);
setTimeout(() => {
promise.status = 'resolved';
promise.then(() => promise.resolve());
}, Math.random() * 3000 + 1000);
};
return (
<div>
<button onClick={handleNotify}>Notify</button>
<ToastContainer limit={limit} />
</div>
);
};
const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
The bug is related to the incorrect processing of promises. In my case, I have to queue a lot of notifications that are tightly dependent on network requests, that may take some time to process. Currently, for some reason, after queueing more promises that are available in the set limit of ToastContainer we get a forever pending promise, that can't somehow be resolved. FYI I can't increase the limit of visible toasts. I have provided a sandbox in case someone doesn't understand the issue. So when the limit is 3, and you try to click the 'Notify' button multiple times (for example 10), after resolving 3 first promises, other ones will be left in a pending state forever.
https://codesandbox.io/s/lingering-cookies-3545w?file=/src/index.js
The expected behavior is in resolving all promises correctly, without any left in pending state.