@restate/core
Version:
_Restate_ is a predictable, easy to use, easy to integrate, typesafe state container for [React](https://reactjs.org/).
50 lines (49 loc) • 1.54 kB
JavaScript
import { useContext, useEffect, useMemo, useState } from "react";
import { BehaviorSubject } from "rxjs";
import { distinctUntilChanged } from "rxjs/operators";
const identitySelectorFunction = (state) => state;
function createSelectorHook(context, outerSelector = identitySelectorFunction) {
function useAppState(selector, props) {
const _store = useContext(context);
const _props = {
deps: [],
compare: void 0,
...props
};
const state = _store.state;
const deps = _props.deps;
const startValue = useMemo(
() => getSelectedValue(state, outerSelector, selector),
[...deps]
);
const [value, setValue] = useState(startValue);
const output$ = useMemo(() => {
return new BehaviorSubject(startValue);
}, [state]);
useEffect(() => {
const stateSub = _store.state$.subscribe((nextStateValue) => {
const nextValue = getSelectedValue(
nextStateValue.state,
outerSelector,
selector
);
output$.next(nextValue);
});
const outputSub = output$.pipe(distinctUntilChanged()).subscribe((nextStateValue) => setValue(nextStateValue));
return function cleanup() {
stateSub.unsubscribe();
outputSub.unsubscribe();
};
}, [output$, ...deps]);
return value;
}
return useAppState;
}
function getSelectedValue(state, outerSelector, selector) {
const subState = outerSelector(state);
const value = selector(subState);
return value;
}
export {
createSelectorHook
};