react-obsidian
Version:
Dependency injection framework for React and React Native applications
32 lines (26 loc) • 893 B
text/typescript
/* eslint-disable no-param-reassign */
import {
useCallback,
useEffect,
useMemo,
useState,
} from 'react';
import { Observable } from './Observable';
type ObservableOrGenerator<T> = Observable<T> | (() => Observable<T>);
export function useObserver<T>(observableOrGenerator: ObservableOrGenerator<T>): [T, (next: T) => void] {
const observable = useMemo(
() => getOrGenerateObservable(observableOrGenerator),
[],
);
const [value, setValue] = useState(observable.value);
const onNext = useCallback((next: T) => {
observable.value = next;
}, [observable]);
useEffect(() => {
return observable.subscribe(setValue);
}, [observable]);
return [value, onNext];
}
function getOrGenerateObservable(observableOrGenerator: ObservableOrGenerator<any>) {
return observableOrGenerator instanceof Observable ? observableOrGenerator : observableOrGenerator();
}