Kopie van https://gitlab.com/studieverenigingvia/ict/centurion met een paar aanpassingen
You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
49 lines
1.1 KiB
49 lines
1.1 KiB
import { useEffect, useState } from "react";
|
|
|
|
export class Sub<T> {
|
|
_listeners: ((obj: T) => void)[] = [];
|
|
_current: T | null = null;
|
|
|
|
subscribe(listener: any) {
|
|
if (this._listeners.indexOf(listener) < 0) {
|
|
this._listeners.push(listener);
|
|
}
|
|
}
|
|
|
|
unsubscribe(listener: any) {
|
|
const index = this._listeners.indexOf(listener);
|
|
if (index >= 0) {
|
|
this._listeners.splice(index, 1);
|
|
}
|
|
}
|
|
|
|
get(): T | null {
|
|
return this._current;
|
|
}
|
|
|
|
set(obj: T) {
|
|
this._current = obj;
|
|
this._listeners.forEach((cb) => cb(obj));
|
|
}
|
|
}
|
|
|
|
export function useSub<T>(
|
|
sub: Sub<T>,
|
|
effectChanges: ((v: T | null) => any[]) | null = null
|
|
): T | null {
|
|
const [currentState, stateSetter] = useState(sub.get());
|
|
|
|
useEffect(
|
|
() => {
|
|
const listener = (obj: T) => stateSetter(obj);
|
|
sub.subscribe(listener);
|
|
return () => sub.unsubscribe(listener);
|
|
// This effect uses "sub" from outside of its scope, should it be a dependency?
|
|
// Ignore the lint warning for now.
|
|
// eslint-disable-next-line
|
|
},
|
|
effectChanges ? effectChanges(currentState) : []
|
|
);
|
|
|
|
return currentState;
|
|
}
|
|
|