forked from coldemo/gallery.code
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathuseModel.ts
More file actions
34 lines (30 loc) · 855 Bytes
/
useModel.ts
File metadata and controls
34 lines (30 loc) · 855 Bytes
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
import _ from 'lodash';
import { Reducer, useMemo, useReducer } from 'react';
interface ActionArgMap<A> {
[type: string]: (...args: any[]) => Omit<A, 'type'> | null;
}
interface ActionMap<A> {
[type: string]: (...args: any[]) => A;
}
export let useModel = <S, A extends { type: string }>(
reducer: Reducer<S, A>,
initialState: S,
_actions: ActionArgMap<A>
) => {
let [state, dispatch] = useReducer<Reducer<S, A>>(reducer, initialState);
let actions = useMemo<ActionMap<A>>(() => {
return _.reduce(
_actions,
(acc, func, k) => {
acc[k] = (...args: any[]) => {
let patch = func(...args);
let action = { type: k, ...patch } as A;
return dispatch(action);
};
return acc;
},
Object.create(null)
);
}, [_actions, dispatch]);
return [state, actions];
};