react-use/src/useMethods.ts
Renovate Bot a27f09fd36
chore: refactoring and rearrangement.
More DRY code. Also move non-hooks to separate directories.

BREAKING CHANGE: all `create*` factories been moved to `factory` subdirectory and in case direct import should be imported like `react-use/esm/factory/createBreakpoint`
BREAKING CHANGE: `comps` directory renamed to `component`
2021-01-30 23:30:26 +03:00

41 lines
1.0 KiB
TypeScript

import { Reducer, useMemo, useReducer } from 'react';
type Action = {
type: string;
payload?: any;
};
type CreateMethods<M, T> = (
state: T
) => {
[P in keyof M]: (payload?: any) => T;
};
type WrappedMethods<M> = {
[P in keyof M]: (...payload: any) => void;
};
const useMethods = <M, T>(createMethods: CreateMethods<M, T>, initialState: T): [T, WrappedMethods<M>] => {
const reducer = useMemo<Reducer<T, Action>>(
() => (reducerState: T, action: Action) => {
return createMethods(reducerState)[action.type](...action.payload);
},
[createMethods]
);
const [state, dispatch] = useReducer<Reducer<T, Action>>(reducer, initialState);
const wrappedMethods: WrappedMethods<M> = useMemo(() => {
const actionTypes = Object.keys(createMethods(initialState));
return actionTypes.reduce((acc, type) => {
acc[type] = (...payload) => dispatch({ type, payload });
return acc;
}, {} as WrappedMethods<M>);
}, [createMethods, initialState]);
return [state, wrappedMethods];
};
export default useMethods;