Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 | 1x 4x 4x 8x 8x 2x 6x 4x 4x 4x 2x 4x | import { type Context, createContext, useContextSelector } from "use-context-selector";
export type ScopedContextValue<TState, TActions> = {
state: TState;
actions: TActions;
};
export type ScopedContextSelector<TValue, TSelected> = (value: TValue) => TSelected;
export type ScopedContext<TState, TActions> = {
Context: Context<ScopedContextValue<TState, TActions> | null>;
useSelector: <TSelected>(
selector: ScopedContextSelector<ScopedContextValue<TState, TActions>, TSelected>,
) => TSelected;
useStateSelector: <TSelected>(selector: ScopedContextSelector<TState, TSelected>) => TSelected;
useActionsSelector: <TSelected>(
selector: ScopedContextSelector<TActions, TSelected>,
) => TSelected;
};
export const createScopedContext = <TState, TActions>(
errorMessage: string,
): ScopedContext<TState, TActions> => {
const Context = createContext<ScopedContextValue<TState, TActions> | null>(null);
const useSelector = <TSelected>(
selector: ScopedContextSelector<ScopedContextValue<TState, TActions>, TSelected>,
): TSelected => {
return useContextSelector(Context, (value: ScopedContextValue<TState, TActions> | null) => {
if (!value) {
throw new Error(errorMessage);
}
return selector(value);
});
};
const useStateSelector = <TSelected>(
selector: ScopedContextSelector<TState, TSelected>,
): TSelected => {
return useSelector((value) => selector(value.state));
};
const useActionsSelector = <TSelected>(
selector: ScopedContextSelector<TActions, TSelected>,
): TSelected => {
return useSelector((value) => selector(value.actions));
};
return {
Context,
useSelector,
useStateSelector,
useActionsSelector,
};
};
|