Skip to content

useSubject

Category
Export Size
274 B
Package
@reause/rxjs
Last Changed
5 days ago

Bind an RxJS Subject to a controllable state and propagate value changes both ways.

Demo

Install

bash
npm i rxjs

Usage

tsx
import { 
useSubject
} from '@reause/rxjs'
import {
Subject
} from 'rxjs'
const
subject
= new
Subject
<string>()
export function
Component
() {
const [
value
,
setValue
] =
useSubject
(
subject
)
return ( <
input
value
={
value
?? ''}
onChange={
e
=>
setValue
(
e
.target.value)}
/> ) }

setValue calls subject.next(...), so the subject stays the single source of truth: a write is pushed into the subject and the state follows the emission that comes back through the subscription — which also means every other subscriber observes the write. Values emitted by the subject (subject.next('from subject')) update the state as well. The subscription is created once on mount and unsubscribed on unmount, so a new subject identity on a later render neither re-subscribes nor re-targets setValue.

With BehaviorSubject

When using a BehaviorSubject, the state is initialized with the subject's current value and the type does not include undefined:

tsx
import { 
useSubject
} from '@reause/rxjs'
import {
BehaviorSubject
} from 'rxjs'
const
subject
= new
BehaviorSubject
('initial')
const [
value
,
setValue
] =
useSubject
(
subject
) // string, not string | undefined
console
.
log
(
value
) // 'initial'

Error Handling

If you want to add custom error handling to a Subject that might error, you can supply an optional onError configuration. Without this, RxJS will treat any error in the supplied subject as an "unhandled error" and it will be thrown in a new call stack and reported to window.onerror (or process.on('error') if you happen to be in Node).

tsx
import { 
useSubject
} from '@reause/rxjs'
import {
Subject
} from 'rxjs'
const
subject
= new
Subject
()
const [
value
,
setValue
] =
useSubject
(
subject
, {
onError
: (
err
) => {
console
.
log
(
err
.message) // "oops"
}, })

Type Declarations

ts
export type UseSubjectOptions<I = undefined> = Omit<UseObservableOptions<I>, 'initialValue'>

export type UseSubjectReturn<H> = [
    value: H,
    setValue: Dispatch<SetStateAction<H>>
]

export interface UseObservableOptions<I> {
    onError?: (err: unknown) => void;
    initialValue?: I | undefined;
}

export function useSubject<H>(subject: BehaviorSubject<H>, options?: UseSubjectOptions): UseSubjectReturn<H>

export function useSubject<H>(subject: Subject<H>, options?: UseSubjectOptions): UseSubjectReturn<H | undefined>

export function useObservable<H, I = undefined>(observable: Observable<H>, options?: UseObservableOptions<I | undefined>): UseObservableReturn<H, I>

Source

Source · Demo

Contributors

hairyf

Changelog

v0.1.0 on
7340a - feat(rxjs): implement useSubject (#218)

Released under the MIT License. v0.1.8