Skip to content

Instantly share code, notes, and snippets.

@erickvieira
Last active October 26, 2020 13:41
Show Gist options
  • Save erickvieira/48d4d30e299a483c1e46c92ce6b42cf2 to your computer and use it in GitHub Desktop.
Save erickvieira/48d4d30e299a483c1e46c92ce6b42cf2 to your computer and use it in GitHub Desktop.
ReactJS Hook to create a RxJS based state and share it between React.FC components. No matters what level the state had been created, it will be available on whole app scope due to the BehaviorSubject. Read more about this approach here: https://medium.com/@thomasburlesonIA/https-medium-com-thomasburlesonia-react-hooks-rxjs-facades-4e116330bbe1 |
import { BehaviorSubject } from "rxjs"; // remember to install rxjs dependency
import { useCallback, useEffect, useState } from "react";
import { skip } from "rxjs/operators";
const globalSubject = new BehaviorSubject<any>({});
type SetSharedStateAction<S> = (state: S) => void;
export default function <T>(
subject: BehaviorSubject<T> = globalSubject
): [T, SetSharedStateAction<T>] {
const [state, setState] = useState(subject.getValue());
useEffect(() => {
const subscription = subject
.pipe(skip(1))
.subscribe((data) => setState(data));
return () => subscription.unsubscribe();
});
const setStateProxy = useCallback((state: T) => subject.next(state), [
subject,
]);
return [state, setStateProxy];
}
// An example of "store" object to use as param in useSharedState hook.
import { BehaviorSubject } from "rxjs";
type Example = {
foo: Foo;
bar: Bar;
};
export default new BehaviorSubject<Example | undefined>(undefined);
import useSharedState from "hooks/useSharedState";
import xStore from "store/xStore";
export const MyComponent: React.FC = () => {
// ...
const [state, setState] = useSharedState(xStore);
// ...
return (
<div>
<h1>{state?.foo}</h1>
<p>{state?.bar}</p>
</div>
)
}
@erickvieira
Copy link
Author

The files with x prefix are only examples to illustrate an use case.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment