Advertisement
Guest User

Untitled

a guest
Feb 23rd, 2022
149
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. /// Throw this in a file somewhere
  2. import { useCallback, useEffect, useState } from 'react';
  3.  
  4. export class SharedState<T> {
  5.     private readonly watchers: ((v: T) => void)[] = [];
  6.  
  7.     constructor(public value: T) {}
  8.  
  9.     watch(watcher: (v: T) => void) {
  10.         this.watchers.push(watcher);
  11.     }
  12.  
  13.     removeWatcher(watcher: (v: T) => void) {
  14.         const index = this.watchers.indexOf(watcher);
  15.         this.watchers.splice(index, 1);
  16.     }
  17.  
  18.     setValue(newValue: T) {
  19.         this.value = newValue;
  20.         for(const watcher of this.watchers) {
  21.             watcher(newValue);
  22.         }
  23.     }
  24. }
  25.  
  26. export function useSharedState<T>(sharedState: SharedState<T>): [T, (newValue: T) => void] {
  27.     const [value, setValue] = useState(sharedState.value);
  28.     useEffect(() => {
  29.         sharedState.watch(setValue);
  30.         return () => sharedState.removeWatcher(setValue);
  31.     }, [sharedState]);
  32.     return [value, useCallback((newValue: T) => sharedState.setValue(newValue), [sharedState])];
  33. }
  34.  
  35. /// Then define your shared state objects (I like to do this in a separate file)
  36. export const exampleSharedState = new SharedState('asd');
  37.  
  38. /// Example usage
  39. import { exampleSharedState } from "../wherever/you/put/your/shared/state";
  40.  
  41. function ComponentUsingSharedState(props) {
  42.     const [example, setExample] = useSharedState(exampleSharedState);
  43.     // Works exactly the same way as useState, but updates will propagate to any component that uses it
  44.     return <div onClick={() => setExample('clicked')}>example</div>;
  45. }
  46.  
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement