reactant-module
Version:
A module model for Reactant
62 lines (60 loc) • 1.55 kB
text/typescript
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
) => {
const store = target[storeKey];
// 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 (store) {
store.dispatch(action);
} else {
throw new Error(
`Store for '${target.constructor.name}' service does not exist. Please make sure you have set any Redux state, or it should not be executed synchronously in class constructor.`
);
}
};