Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- /// Throw this in a file somewhere
- import { useCallback, useEffect, useState } from 'react';
- export class SharedState<T> {
- private readonly watchers: ((v: T) => void)[] = [];
- constructor(public value: T) {}
- watch(watcher: (v: T) => void) {
- this.watchers.push(watcher);
- }
- removeWatcher(watcher: (v: T) => void) {
- const index = this.watchers.indexOf(watcher);
- this.watchers.splice(index, 1);
- }
- setValue(newValue: T) {
- this.value = newValue;
- for(const watcher of this.watchers) {
- watcher(newValue);
- }
- }
- }
- export function useSharedState<T>(sharedState: SharedState<T>): [T, (newValue: T) => void] {
- const [value, setValue] = useState(sharedState.value);
- useEffect(() => {
- sharedState.watch(setValue);
- return () => sharedState.removeWatcher(setValue);
- }, [sharedState]);
- return [value, useCallback((newValue: T) => sharedState.setValue(newValue), [sharedState])];
- }
- /// Then define your shared state objects (I like to do this in a separate file)
- export const exampleSharedState = new SharedState('asd');
- /// Example usage
- import { exampleSharedState } from "../wherever/you/put/your/shared/state";
- function ComponentUsingSharedState(props) {
- const [example, setExample] = useSharedState(exampleSharedState);
- // Works exactly the same way as useState, but updates will propagate to any component that uses it
- return <div onClick={() => setExample('clicked')}>example</div>;
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement