react-toastify
react-toastify copied to clipboard
Remounting the `ToastContainer` causes it to lose state
I'm trying to use react-toastify in an app that uses HTML <dialog> elements for modals. Due to the issues described here, in order to make this work with toast notifications, I need to use createPortal() to render the <ToastContainer/> inside the <dialog>. Otherwise toasts will be (1) rendered behind the modal, and (2) will not be interactive because they're in the "inert" part of the document.
I'm using createPortal() to render the <ToastContainer/> in the top-most <dialog> modal. However, if any toast messages are already open, this state is lost when the modal is opened/closed.
It seems that the state itself is already stored in a single global store (given that containerId is constant). So it should be possible for the <ToastContainer/> to get this state on re-mount so that it shows any toast messages that are already there.
Exactly, this is the issue we are facing right now (before, we only displayed one toast at a time by flushing and dismissing everything else each time a new toast was triggered), but with multiple toasts, it doesn't retain the state.
The autoclose timer also resets, so if it was close to auto-closing, it restarts.
Using moveBefore to move things rather than remounting keeps the current state.
Might be a while before it's everywhere without polyfills though 😢
@Link2Twenty You mentioned polyfills, but moveBefore is not polyfill-able to my knowledge? Unless I missed something.
In any case I basically ended up having to write my own toast implementation because of this issue, as far as I can tell there's no way to make it work with the library as is. In previous versions we could maybe make it work by rolling a custom ToastProvider but the internal definitions are no longer exposed.
I've got a simplistic polyfil in here (though it in no way does everything moveBefore does), that keeps the state when moving the toast container.
https://codesandbox.io/p/sandbox/htj44g
@Link2Twenty Oh awesome, thanks for that. I might adopt it. Currently in my implementation I just set a flag to prevent animations from running again after the remount, but it's not as seamless as your polyfill.