A hook for integrating RxJS observables with React.
const [value, next, error, complete] = useObservable(obs$ => obs$.pipe( /* ... */ ), 'initial value')| import { useState, useEffect, useMemo, useCallback } from 'react' | |
| import { Subject, isObservable } from 'rxjs' | |
| function useObservable(generateEnhancedObservable, initValue) { | |
| const sub$ = useMemo(() => new Subject(), []) | |
| const next = useCallback(sub$.next.bind(sub$), []) | |
| const [value, setValue] = useState(initValue) | |
| const [error, setError] = useState(null) | |
| const [complete, setComplete] = useState(false) | |
| useEffect(() => { | |
| const obs$ = sub$.asObservable() | |
| const enhanced$ = typeof generateEnhancedObservable === 'function' | |
| ? generateEnhancedObservable(obs$) | |
| : obs$ | |
| if (!isObservable(enhanced$)) { | |
| throw new Error('The function passed to "useObservable" does not return an observable') | |
| } | |
| const subscription = enhanced$.subscribe({ | |
| next: value => { | |
| setValue(value) | |
| setError(null) | |
| }, | |
| error: err => setError(err instanceof Error ? err.message : err), | |
| complete: () => setComplete(true) | |
| }) | |
| return () => subscription.unsubscribe() | |
| }, []) | |
| return [value, next, error, complete] | |
| } | |
| export default useObservable |