-
Notifications
You must be signed in to change notification settings - Fork 33
/
reducerUtils.ts
67 lines (63 loc) · 1.75 KB
/
reducerUtils.ts
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
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
import { AnyAction } from 'redux';
import { getType, AsyncActionCreator } from 'typesafe-actions';
export type AsyncState<T, E = any> = {
data: T | null;
loading: boolean;
error: E | null;
};
export const asyncState = {
// 다음 코드는 화살표 함수에 Generic 을 설정 한 것입니다.
initial: <T, E = any>(initialData?: T): AsyncState<T, E> => ({
loading: false,
data: initialData || null,
error: null
}),
load: <T, E = any>(data?: T): AsyncState<T, E> => ({
loading: true,
data: data || null,
error: null
}),
success: <T, E = any>(data: T): AsyncState<T, E> => ({
loading: false,
data,
error: null
}),
error: <T, E>(error: E): AsyncState<T, E> => ({
loading: false,
data: null,
error: error
})
};
type AnyAsyncActionCreator = AsyncActionCreator<any, any, any>;
export function transformToArray<AC extends AnyAsyncActionCreator>(asyncActionCreator: AC) {
const { request, success, failure } = asyncActionCreator;
return [request, success, failure];
}
export function createAsyncReducer<S, AC extends AnyAsyncActionCreator, K extends keyof S>(
asyncActionCreator: AC,
key: K
) {
return (state: S, action: AnyAction) => {
// 각 액션 생성함수의 type 을 추출해줍니다.
const [request, success, failure] = transformToArray(asyncActionCreator).map(getType);
switch (action.type) {
case request:
return {
...state,
[key]: asyncState.load()
};
case success:
return {
...state,
[key]: asyncState.success(action.payload)
};
case failure:
return {
...state,
[key]: asyncState.error(action.payload)
};
default:
return state;
}
};
}