ChangeNotifier.ts
export class ChangeNotifier {
protected listeners = new Set<() => void>();
listen(listener: () => void) {
this.listeners.add(listener);
return () => {
this.listeners.delete(listener);
};
}
notify() {
this.listeners.forEach((listener) => listener());
}
}
useChangeNotifierState.tsx
export const useChangeNotifierState = <T extends ChangeNotifier, U>(
source: T,
selector: (s: T) => U,
) => {
const [value, setValue] = useState<U>(selector(source));
useEffect(() => {
return source.listen(() => setValue(selector(source)));
}, [source]);
return value;
};