Skip to content

Instantly share code, notes, and snippets.

@RStankov
Created June 25, 2020 11:48
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save RStankov/c4eec654d25bf0bf0252c8faa0a3bd1c to your computer and use it in GitHub Desktop.
Save RStankov/c4eec654d25bf0bf0252c8faa0a3bd1c to your computer and use it in GitHub Desktop.
export default miniStateMachine<IComponentProps>({
initialState,
actions,
components: {
search: Search,
newProduct: NewProduct,
product: Poduct,
},
// WIP
onChangeProp: 'prop',
onChange:(state, props: IComponentProps) {
},
});
import * as React from 'react';
type ReplaceReturnType<T extends (...a: any) => any, TNewReturn> = (
...a: Parameters<T>
) => TNewReturn;
type OmitFirstArg<F> = F extends (x: any, ...args: infer P) => infer R
? (...args: P) => R
: never;
export type ExtractDispatch<T extends object> = {
[K in keyof T]-?: ReplaceReturnType<OmitFirstArg<T[K]>, void>;
};
export default function useMiniReducer<TState, TActions extends object>(
actions: TActions,
initialState: TState,
): [TState, ExtractDispatch<TActions>] {
const [state, setState] = React.useState<TState>(initialState);
return React.useMemo(() => {
const dispatch = new Proxy(actions, {
get(obj: any, prop) {
return (...args: any) => {
setState(obj[prop](state, ...args));
};
},
}) as any;
return [state, dispatch];
}, [state, setState, actions]);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment