You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In the gravity-ui library, there are several ways to invoke a toast (a notification window at the edge of the screen): through the useToaster hook or, where hooks are not applicable, through the Toaster singleton.
However, when using the singleton approach, a problem may arise where components rendered within such a toast do not have access to various application providers, because these toasts are mounted in a different root.
Using both approaches in a single project can lead to issues with toasts overlapping each other, as each method has its own stack of toasts. (An example is shown in the video.)
Solution Proposal
Create a universal API with methods that do not conflict with each other. This could be implemented similar to Redux, where a singleton is passed into a provider and can also be used externally.
importReact,{createContext,useContext,useState,useMemo,useEffect}from"react";exportconstToasterContext=createContext(null);ToasterContext.displayName="ToasterContext";exportconstToasterProvider=({ toaster, children })=>{const[toasts,setToasts]=useState([]);useEffect(()=>{constupdateToasts=(toasts)=>{setToasts((prev)=>[...toasts]);};toaster.on(updateToasts);return()=>{toaster.off(updateToasts);};},[toaster]);return(<ToasterContext.Providervalue={toaster}><>{children}<div>{toasts.map((toast)=>(<div>{toast}</div>))}</div></></ToasterContext.Provider>);};exportconstuseToaster=()=>{consttoaster=useContext(ToasterContext);returnuseMemo(()=>toaster,[toaster]);};classToaster{constructor(){this.toasts=[];this.listeners=[];}add(toast){this.toasts.push(toast);for(constlistenerofthis.listeners){listener(this.toasts);}}on(fn){this.listeners.push(fn);}off(fn){this.listeners=this.listeners.filter((listener)=>listener!==fn);}}consttoaster=newToaster();functionSomeComponent(){consttoasterFromHook=useToaster();consthandleClick=()=>{toasterFromHook.add("a new fresh toast");};return<buttononClick={handleClick}>Addtoast</button>;}setTimeout(()=>{toaster.add('toast from setTimeout');},3000);exportdefaultfunctionApp(){return(<divclassName="App"><ToasterProvidertoaster={toaster}><SomeComponent/></ToasterProvider></div>);}
The main idea is to create an object that maintains the state of toasts and allows subscribing to its changes. Essentially, it's the same concept as redux + react-redux. This way, the object is created once in the service and then used as needed.
This is my initial thought, but if someone suggests something simpler, I'd be happy to take a look :)
Definition of done
A pull request is made with a universal, non-conflicting API.
The text was updated successfully, but these errors were encountered:
Objective
In the gravity-ui library, there are several ways to invoke a toast (a notification window at the edge of the screen): through the useToaster hook or, where hooks are not applicable, through the Toaster singleton.
However, when using the singleton approach, a problem may arise where components rendered within such a toast do not have access to various application providers, because these toasts are mounted in a different root.
Using both approaches in a single project can lead to issues with toasts overlapping each other, as each method has its own stack of toasts. (An example is shown in the video.)
Solution Proposal
Create a universal API with methods that do not conflict with each other. This could be implemented similar to Redux, where a singleton is passed into a provider and can also be used externally.
Rough implementation
Click to expand
The main idea is to create an object that maintains the state of toasts and allows subscribing to its changes. Essentially, it's the same concept as redux + react-redux. This way, the object is created once in the service and then used as needed.
This is my initial thought, but if someone suggests something simpler, I'd be happy to take a look :)
Definition of done
A pull request is made with a universal, non-conflicting API.
The text was updated successfully, but these errors were encountered: