Where should I declare my BehaviorSubject when using React Hooks with RxJS?

Viewed 617

I tried to follow along this implementation from React Hooks + RxJS or How React Is Meant to Be. It looks promising. You simply have this custom hook:

const useSharedState = subject => {
 const [value, setState] = useState(subject.getValue());
 useEffect(() => {
   const sub = subject.pipe(skip(1)).subscribe(s => setState(s));
   return () => sub.unsubscribe();
 });
 const newSetState = state => subject.next(state);
 return [value, newSetState];
};

And You can just basically use it as:

const subject = new BehaviorSubject({ message: '' });

const AwesomeComponent = () => {
 const [{ message }, setState] = useSharedState(subject); // Custom Hook
 return <div>{message}</div>;
};

The only thing I am not sure of is where exactly SHOULD I declare my subject ? If I put it on the file of the component, will it persist? I can't seem to imagine how the instance is persisted when the component is not used yet or if it will persist when the component is destroyed/unmounted? Especially when I do an API call (for example, using axios-observable), I don't know how exactly it should be done along with this custom hook.

1 Answers

This is what I like to do:

import { useCallback, useState } from "react";
import { BehaviorSubject } from "rxjs";

export const useBehaviorSubject = <T>(initialState: T): [BehaviorSubject<T>, (x: T) => void] => {
    const [observable] = useState(new BehaviorSubject<T>(initialState));

    const handleNext = useCallback(
        (value: T) => {
            observable.next(value);
        },
        [observable],
    );

    return [observable, handleNext];
};
Related