react-toastify icon indicating copy to clipboard operation
react-toastify copied to clipboard

Cannot update toast before queue shows it

Open santi8194 opened this issue 4 years ago • 5 comments

When there is a limit to the number of toasts displayed, if I create a toast that cannot be displayed yet and I try to update it, when the toast appears, it is in the state that created it not the updated state.

Steps to reproduce:

  1. Set a limit to the number of toasts displayed (3 toasts)
  2. Create 4 toasts sequentially
  3. After creating the fourth toast, update it Bug: the fourth toast never updates.

Edit silent-dawn-2c2rm

The toasts not displayed yet and are in the queue should also update

Tested on: "@babel/runtime": "7.13.8", "react": "17.0.1", "react-dom": "17.0.1", "react-scripts": "4.0.0", "react-toastify": "7.0.3"

santi8194 avatar Mar 05 '21 16:03 santi8194

Hey @santi8194, thank you for providing the codesandbox. This is a limit to the current implementation. Only rendered toast can be updated. From what I see, this would require adding ~2-3 lines of code.

fkhadra avatar Apr 20 '21 19:04 fkhadra

Does anyone have a solution for this? I'm also seeing this issue, only active toasts are being updated and this is causing me issues. Any toasts that go beyond the limit do not get updates, and therefore never clear.

garygoodger avatar Nov 21 '21 14:11 garygoodger

I think this issue also applies to situation when you try to update the toast too soon (before it is fully rendered).

bartektartanus avatar Nov 30 '21 12:11 bartektartanus

This issue has been open for over 2 years now; Any update on it?

ashercoren avatar Jul 05 '23 07:07 ashercoren

Tried using this workaround on v9.1.3:

function performToastUpdate<TData = unknown>(toastId: React.ReactText, options: UpdateOptions<TData>) {
    if (toast.isActive(toastId)) {
      toast.update(toastId, options);
      return;
    }

    const removeCallback = toast.onChange((x) => {
      if (x.status === 'removed') {
        removeCallback();
      }
      if (x.status === 'added') {
        toast.update(toastId, options); // wrap this in setTimeout helps, but still fails regularly
      }
    });
  }

but it doesn't work consistently because the toast event is fired before the previous toast is collapsed and the new toast is truly rendered. Wrapping the deferred update in a very large timeout helps but does create some other jank, and even with a timeout of >1 second there are still some cases where a new toast doesn't get updated properly.

irwincollin avatar Feb 23 '24 21:02 irwincollin