mirror of
https://github.com/streamich/react-use.git
synced 2026-01-18 14:06:52 +00:00
Also reduce max line width to 100. And remove `lint:types` step for commit sequence, it bothers when committing incomplete (wip) changes.
44 lines
1.0 KiB
TypeScript
44 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;
|