timolins / react-hot-toast

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

bug: toast remains in the DOM if call programmatically. #101

Open weeebdev opened 3 years ago

weeebdev commented 3 years ago

I was writing tests for my custom toast wrapped around react-hot-toast and faced with the bug where my toast persisted at the DOM tree. I decided to try the original lib and it happened again.

Just try:

import { useEffect } from "react";
import toast, { Toaster } from "react-hot-toast";

function App() {
  useEffect(() => {
    for (let index = 0; index < 10; index++) {
      toast.success(index + "");
    }
  }, []);

  return (
    <div className="App">
      <Toaster />
      <button onClick={() => toast.success("Hello!")}>Click!</button>
    </div>
  );
}

export default App;

image

Same happens if I click on the button very fast, some toasts remain in the DOM.

Is there a way to fix it? Will be very glad, if there is a workaround

alexandredev3 commented 3 years ago

Maybe this can help:

import { useEffect } from "react";
import toast, { Toaster, useToaster } from "react-hot-toast";

export default function App() {
  const { toasts } = useToaster();

  useEffect(() => {
    // this line will ensure that all toasts are remove from the DOM when their duration expires.
    toasts.forEach((item) => {
      if (!item.visible) {
        toast.remove(item.id);
      }
    });
  }, [toasts]);

  useEffect(() => {
    for (let index = 0; index < 10; index++) {
      toast.success(index + "");
    }
  }, []);

  return (
    <div className="App">
      <Toaster />
      <button onClick={() => toast.success('Hello!')}>Click!</button>
    </div>
  );
}
timolins commented 3 years ago

Interesting, thanks for reporting. I'll have a closer look.

bruce-c-liu commented 1 year ago

Bump.

cmmartin commented 1 year ago

Fixed by https://github.com/timolins/react-hot-toast/pull/251. @timolins can we get this merged?