Skip to content

Instantly share code, notes, and snippets.

@alfrescian
Created April 9, 2019 07:01
Show Gist options
  • Select an option

  • Save alfrescian/2a23b7732f1821b1b8cc33b4ad594086 to your computer and use it in GitHub Desktop.

Select an option

Save alfrescian/2a23b7732f1821b1b8cc33b4ad594086 to your computer and use it in GitHub Desktop.
useSimpleState hook
import React, {
createContext,
useContext,
useReducer,
Reducer,
Context,
Dispatch,
ReactNode,
Provider,
ReactElement
} from 'react';
export type SimpleStateReducer<S extends object, A extends SimpleStateAction> = Reducer<S, A>;
export type UseSimpleStateReducer<S extends object, A extends SimpleStateAction> = [S, Dispatch<A>];
export type SimpleStateContext<S extends object, A extends SimpleStateAction> = Context<UseSimpleStateReducer<S, A>>;
interface StateProviderProps<S extends object, A extends SimpleStateAction> {
reducer: SimpleStateReducer<S, A>;
initialState: S;
children: ReactNode;
}
// eslint-disable-next-line @typescript-eslint/no-explicit-any
export interface SimpleStateAction<T = string, P = any> {
type: T;
payload: P;
}
type StateProvider<S extends object, A extends SimpleStateAction> = (
stateProviderInput: StateProviderProps<S, A>
) => ReactElement<Provider<S>>;
interface SimpleState<S extends object, A extends SimpleStateAction> {
useSimpleState: () => UseSimpleStateReducer<S, A>;
StateProvider: StateProvider<S, A>;
}
export function simpleStateFactory<S extends object, A extends SimpleStateAction>(): SimpleState<S, A> {
const StateContext: SimpleStateContext<S, A> = createContext(([] as unknown) as UseSimpleStateReducer<S, A>);
const StateProvider: StateProvider<S, A> = ({ reducer, initialState, children }: StateProviderProps<S, A>) => (
<StateContext.Provider value={useReducer(reducer, initialState)}>{children}</StateContext.Provider>
);
const useSimpleState = () => useContext(StateContext);
return { useSimpleState, StateProvider };
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment