-
Notifications
You must be signed in to change notification settings - Fork 14
/
dispatch.ts
60 lines (59 loc) · 1.44 KB
/
dispatch.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
import { AnyAction } from 'redux';
import { ThisService } from '../interfaces';
import { storeKey } from '../constants';
/**
* ## Description
*
* It is used for compatibility with redux actions,
* when a class state with actions is being migrated from the Redux boilerplate code to the Reactant.
* And it's often used in conjunction with `createState()`.
*
* ## Example
*
* ```ts
* const type = 'count_increase';
*
* interface CountAction {
* type: typeof type;
* state: number;
* }
*
* @injectable()
* class Counter {
* @state
* count = createState<CountAction['state'], CountAction>(
* ($state = 0, $action) => ($action.type === type ? $action.state : $state)
* );
*
* increase() {
* dispatch<CountAction>(this, {
* type,
* state: this.count + 1,
* });
* }
* }
*
* const app = createApp({
* modules: [],
* main: Counter,
* render: () => {},
* });
*
* app.instance.increase();
* expect(app.instance.count).toBe(1);
* ```
*/
export const dispatch = <T extends AnyAction = AnyAction>(
target: ThisService,
action: T
) => {
// the api should not be implemented as a decorator
// (because it should return new state should get a the current new state, low performance.)
if (target[storeKey]) {
target[storeKey]!.dispatch(action);
} else {
throw new Error(
`Store for '${target.constructor.name}' service does not exist, and make sure you have set any Redux state.`
);
}
};