timolins / react-hot-toast

Smoking Hot React Notifications 🔥
https://react-hot-toast.com
MIT License
9.79k stars 331 forks source link

"duration" not working anymore after clicking on "onClick" on mobile #128

Open gandreini opened 3 years ago

gandreini commented 3 years ago

This problem happens on mobile, so it can be tested on Google Chrome Developer tools or directly on a mobile device.

How to reproduce the problem on Codesandbox

  1. Launch the developer tools of Google Chrome (or use a mobile device)
  2. Activate the mobile/device toolbar (or use a mobile device)
  3. Reload the application
  4. Click the "Dismiss" button in "Toast 2" before the "Toast 1" has disappeared

Expected behaviour

What actually happens

It seems to me that after I fire toast.dismiss(t.id); for a certain toast, all the duration setting of the other toasts are ignored and thus they won't disappear. Codesandbox here: https://codesandbox.io/s/strange-perlman-x3i3b (to see the issue, please use the Google Chrome Developer tools or directly on a mobile device).

Did I misunderstood something?

gandreini commented 3 years ago

UPDATE

It seems that the problem is not toast.dismiss(t.id), but the onClick. The problem exists also with a simple button like this:

<button onClick={() => { console.log("Test") }}>
  Click
</button>

After i click on that button (that only logs in the console) the current and all the following Toasts will not disappear, ignoring the duration setting.

akhalinem commented 2 years ago

@gandreini I am facing the same issue.

laukaichung commented 2 years ago

You can replicate the issue on the demo page on a mobile phone. Click "Success" toast, immediately click "JSX Content" toast, click its dismiss button. The success toast never disappears.

josh-stillman commented 2 years ago

We hit a similar issue where the toast duration was ignored on ipad and the toasts would no longer auto-dismiss. (Duration still works on desktop). We ended up working around this by setting a timeout in the toast component:

  useEffect(() => {
    setTimeout(() => toast.dismiss(toastInstance.id), 5000);
  }, []);
gitflash commented 10 months ago

We are facing a similar issue , wondering what is the state of this issue ?

pedrovgs commented 10 months ago

We are facing a similar issue. As soon as you dismiss programmatically any toast, the duration param is ignored and no longer works. It is only reproducible on mobile, it works as expected on desktop.

To solve the issue we had to manually resume toast management before we invoke dismiss function using the toast id:


export const Dismiss = ({ toastId }: DismissProps) => {
    const toaster = useToaster();
    return (
        <SecondarySmallButton
            text={i18next.t("document.offline.toast_went_offline.action")}
            onClick={() => {
                // If you don't endPause for this component, other toasts will never dismiss automatically.
                toaster.handlers.endPause();
                // You can now dismiss the toast manually using the toastId here.
            }}
        />
    );
};
ParallelUniv3rse commented 8 months ago

I think I've found a workaround without resorting to a custom useToaster().

The timeout unpause handled by an onMouseLeave handler on the component seems to be able to be run programatically.

I've created a click handler function which runs on the onClick in my custom toast.

const clickHandler = useCallback((e) => {
    const mouseLeaveEvent = new MouseEvent('mouseout', {
      bubbles: true,
      cancelable: true,
    });

    e.currentTarget.dispatchEvent(mouseLeaveEvent);

    t.dismiss(toast.id);
  }, [toast.id]);

React seems to handle it's onMouseLeave via the native mouseout event instead of mouseleave - Don't ask why, I have no idea 😄

This way the toast timer gets unpaused and all works as it should. The lib should still get a patch handling this better - calling the endPause() automatically after .dismiss() or perhaps exposing the pause/unpause functions.