react-hot-toast icon indicating copy to clipboard operation
react-hot-toast copied to clipboard

limit total number of toasts

Open Kilian opened this issue 4 years ago • 31 comments

Hey! Awesome library. Something that would be useful for me is an option to set the maximum number of visible toasts, that will automatically dismiss the oldest one when the maximum is reached.

I could do that with useToaster and a filter but then I would have to replicate everything else <Toaster /> already does, so I would prefer not to.

Kilian avatar Jan 26 '21 15:01 Kilian

That sounds like a reasonable improvement that shouldn't be too hard to implement. Consider this as on the road map.

timolins avatar Jan 26 '21 16:01 timolins

Hey @timolins. I have been looking at some open source projects to contribute to, and this looks like one awesome project I am willing to work on. Would you mind having me look at this issue?

m-yasir avatar Feb 07 '21 21:02 m-yasir

I'm also find this useful, since show multiple toast in a time a bit not needed

Is there any way how to do this with current version? At least without using useToaster

ilhamwahabi avatar Mar 19 '21 10:03 ilhamwahabi

You can achieve by using useToasterStore() & useEffect(). We can read the state of all toasts, and dismiss them if our limit is reached.

const { toasts } = useToasterStore();

const TOAST_LIMIT = 3

useEffect(() => {
  toasts
    .filter((t) => t.visible) // Only consider visible toasts
    .filter((_, i) => i >= TOAST_LIMIT) // Is toast index over limit?
    .forEach((t) => toast.dismiss(t.id)); // Dismiss – Use toast.remove(t.id) for no exit animation
}, [toasts]);

Check out this CodeSandbox example.

timolins avatar Mar 20 '21 14:03 timolins

I think the proposed solution works well enough – no need to add this as native API IMO.

timolins avatar Mar 21 '21 20:03 timolins

We wanted to extend it in a corp ui-kit. Could you add a possibility to change TOAST_LIMIT from <Toaster/> props? Or should I open a PR? https://github.com/timolins/react-hot-toast/blob/0d417d90d7d6c081c33af45eb5d71bd664fcdb1d/src/core/store.ts#L4

I think the proposed solution works well enough – no need to add this as native API IMO.

weeebdev avatar Jul 14 '21 05:07 weeebdev

According to the demand, it's time for a proper API. Will look into this for the next release.

timolins avatar Dec 13 '21 14:12 timolins

Thanks @timolins! I'd be happy to write a PR for this if you'd be open to that?

mcintyre94 avatar Dec 13 '21 15:12 mcintyre94

Any news?

413n avatar Jan 19 '22 16:01 413n

Anything yet @timolins?

brandonrbridges avatar Feb 08 '22 16:02 brandonrbridges

In the meantime, I used @timolins filter solution in a hook so I don't have to write that useEffect everywhere:

useToast.ts

import { useEffect, useState } from "react";
import t, { useToasterStore } from "react-hot-toast";

const useToast = () => {
  const { toasts } = useToasterStore();

  const [toastLimit, setToastLimit] = useState<number>(3);

  useEffect(() => {
    toasts
      .filter((tt) => tt.visible)
      .filter((_, i) => i >= toastLimit)
      .forEach((tt) => t.dismiss(tt.id));
  }, [toasts]);

  const toast = {
    ...t,
    setLimit: (l: number) => {
      if (l !== toastLimit) {
        setToastLimit(l);
      }
    },
  };

  return { toast };
};

export default useToast;

Still, hopefully it'll be part of the native API soon

LuisEgan avatar Feb 22 '22 14:02 LuisEgan

@LuisEgan Yeah, I've used a similar solution as I wanted to set a max limit on mobile devices.

Hoping to have an official API soon.

brandonrbridges avatar Feb 22 '22 14:02 brandonrbridges

I created a custom toaster component based on previous comments,

` const CustomRHToaster = () => { const { toasts } = useToasterStore();

const TOAST_LIMIT = 10;

useEffect(() => { toasts .filter((_toast) => toast.visible) // Only consider visible toasts .filter((, i) => i >= TOAST_LIMIT) // Is toast index over limit? .forEach((_toast) => toast.dismiss(_toast.id)); // Dismiss – Use toast.remove(_toast.id) for no exit animation }, [toasts])

return <Toaster position='top-right' />

} `

jeremiah-olisa avatar Aug 26 '22 04:08 jeremiah-olisa

Any Update guys on this ??

relativelyrehan avatar Jan 18 '23 08:01 relativelyrehan

Any updates on this?

AmirHmZz avatar Jan 25 '23 23:01 AmirHmZz

There's kind of a hack using css -

Give a containerClassName in Toaster -

<Toaster ... containerClassName="toaster-wrapper" ...

And simply put this in your css -

.toaster-wrapper > div { display: none !important; } .toaster-wrapper > div:first-child { display: flex !important; }

and you can use nth-child concept to show the number of toast you want.

belalahmad20 avatar Feb 28 '23 11:02 belalahmad20

Any updates?

Werthis avatar Apr 26 '23 10:04 Werthis

You can create a custom hook to do that

On Wed, 26 Apr 2023, 11:36 am Łukasz, @.***> wrote:

Any updates?

— Reply to this email directly, view it on GitHub https://github.com/timolins/react-hot-toast/issues/31#issuecomment-1523198126, or unsubscribe https://github.com/notifications/unsubscribe-auth/AHNDZFJYSAQ2TKIUBXPROZTXDD3DLANCNFSM4WTVSV2Q . You are receiving this because you commented.Message ID: @.***>

jeremiah-olisa avatar Apr 27 '23 06:04 jeremiah-olisa

if your case its showing the same error unlimited times, you can use the option "id" to prevent this. https://react-hot-toast.com/docs/toast example:

toast.success('Copied to clipboard!', {
 id: 'clipboard',
});```

omateusamaral avatar May 14 '23 18:05 omateusamaral

Any updates @timolins ?

AmirHmZz avatar May 28 '23 01:05 AmirHmZz

if your case its showing the same error unlimited times, you can use the option "id" to prevent this. https://react-hot-toast.com/docs/toast example:

toast.success('Copied to clipboard!', {
 id: 'clipboard',
});```

I tried this method since the other method with toaster store would make the animation very funky and old toasts not disappearing immediately. This method is much nicer since it just replaces the content of the toast. However it since like the last toast would linger for a long time since the duration has been accumulating for the same id? This feels like a bug and shouldnt happen though. The correct behavior should reset the timer but not accumulating it?

siyao-polarr avatar Jun 06 '23 23:06 siyao-polarr

.toaster-wrapper > div { display: none !important; } .toaster-wrapper > div:nth-child(-n+3) { display: flex !important; }

this works

nyctonio avatar Sep 05 '23 13:09 nyctonio

<Toaster ... containerClassName="toaster-wrapper" ...

<Toaster ... containerClassName="toaster-wrapper" ...

nyctonio avatar Sep 05 '23 13:09 nyctonio

Any updates on this? This is a very basic feature that shouldn't be hard to add to the library

NickNaskida avatar Sep 17 '23 06:09 NickNaskida

It is just absurd that the issue has been opened since 2021 and there is still no new addition in the api.

the-iter8 avatar Sep 29 '23 12:09 the-iter8

I think it's time someone create a fix for this and create one PR

relativelyrehan avatar Sep 29 '23 13:09 relativelyrehan

Any update on this? I've just switched to using toastr but I may have to find an alternative if this is not fixed/added.

Shielsy avatar Nov 01 '23 20:11 Shielsy

Please add an inbuilt method/option for this, I had to implement the whole logic my self. 🫠 If possible please add info() and warning() methods. 🙏🏻

pranavgoel29 avatar Nov 18 '23 20:11 pranavgoel29