[bug] ToastId can't be reused!
See original GitHub issueDo you want to request a feature or report a bug?
Bug report!
What is the current behavior?
Thanks for the great library, this is very slick and professional! Unfortunately though, I think I’ve uncovered a bug that badly affects how I want to use it.
Basically, I’m using toastIds in order to prevent duplicate toasts from being displayed.
This works pretty well usually but on occasion it appears that when a toast expires and therefore disappears from view that behind the scenes the toastId doesn’t actually get cleared from memory (or it may get removed but mistakenly added back somehow). When this happens, it has the effect of preventing any further toasts with that same toastId from ever being displayed again! Even though the toast has obviously expired and long gone and that toastId ought to be able to be re-used, it can’t!
If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem. Your bug will get fixed much faster if we can run your code and it doesn’t have dependencies other than React. Paste the link to your CodeSandbox (https://codesandbox.io/s/new) example below:
I’ve found the following helps to reproduce the problem:-
The issue tends to appear when a toast has expired and is in the process of completing its exit animation (in my case I’m using ‘Slide’). If another toast with the same toastId is launched just at the exact time that the first toast completes its exit animation, then it looks like the new toast appears momentarily sliding in but then doesn’t complete its entrance animation and suddenly disappears! When I see that happening, I know that the bug has occurred and that at this point the toastify system thinks that the toast with that toastId is ‘active’ even though it’s no longer being displayed and will also never expire and so that toastId is now permanently locked as ‘active’ preventing any other toasts with that same id from being launched.
So, it would seem that there is some interaction or interference between the new toast being launched and the previous toast exiting when they both have the same toastId, possibly due to some kind of race condition.
When the issue happens, if I query the status of that toast with toast.isActive(myToastId)
then it will return true even though the toast has obviously expired (i.e. it’s not being displayed) and should have been removed from memory. This proves that toastify system has either incorrectly held on to the toastId that just exited or else the toast that just exited has corrupted somehow the newly introduced toast, making it disappear but retaining its toastId in memory so that it will never expire.
The issue is difficult to reproduce accurately, but happens often enough to be troublesome. I can typically reproduce it about one in every 10 (or less) attempts, but the timing is key.
Unfortunately I don’t have a sandbox for this at the moment, but I’m not sure creating a sandbox for it would do any good because it seems to be mostly a timing issue, which might be hard to reproduce programmatically - you have to create a new toast just as the old one is exiting. I’m pretty sure this should be demonstrable with any simple toastify implementation if you time it right. I don’t think it’s due to any issue with my implementation as I’m using it in a fairly simple and straightforward way.
It looks like possibly this issue may be related to this one - “Recreate Toast after hiding using toastId #483” ?
What is the expected behavior?
I would expect that when a toast with a particular toastId expires that same toastId would be available for subsequent re-use.
I would expect that there would be no interactions between two toasts, where the first toast is exiting and the second toast is starting up, where both toasts have the same toastId. The first toast exiting should not corrupt or affect the second toast.
Which versions of React, and which browser / OS are affected by this issue? Did this work in previous versions of React?
I’m using react v16.9.0 and react-toastify v6.0.9 This is my first time using react-toastify so no previous history.
Thanks!
Issue Analytics
- State:
- Created 3 years ago
- Reactions:4
- Comments:9 (4 by maintainers)
Top GitHub Comments
I can confirm that it still happens on version 7.0.3
How it happens for me is that I have an app that have toast notifications triggered by events coming from websockets.
If I open two tabs and trigger a notification from the first one to the second one which is in background and then switch to it I can see the notification properly showing. Then I go to the first tab trigger cancel which closes the notification in the second tab and then trigger open again. Switching to the second tab does not show the notification anymore since it has the same toastId for that notification type.
I am not sure how I can setup codesandbox with this case as it is quite complicated and specific to our project, but I hope it sheds some light on the possible cause.
EDIT: This seems to happen only when the tab is in background, e.g. not in focus. When it is on focus it works ok.
Damn I’ll reopen the issue then