Follow Redux
Tsynringe + reflect-decorator 를 활용해서 Redux와 비슷한 단일 스토어 상태관리 도구를 만들어 보자.
Base Store
/* eslint-disable no-underscore-dangle */
export type Action<P = unknown> = {
type: string;
payload?: P;
};
export type Reducer<S, P> = (state: S, action: Action<P>) => S;
export type Reducers<S, P> = Record<string, Reducer<S, P>>;
type Listener = () => void;
export default class BaseStore<S> {
private listeners = new Set<Listener>();
public reducer: Reducer<S, unknown>;
// eslint-disable-next-line no-useless-constructor
constructor(private _state: S, reducers: Reducers<S, any>) {
this.reducer = (state: S, action: Action<unknown>) => {
const reducer = Reflect.get(reducers, action.type);
if (!reducer) {
return state;
}
return reducer(state, action);
};
}
get state() {
return this._state;
}
dispatch(action: Action<unknown>) {
this._state = this.reducer(this._state, action);
this.publish();
}
protected publish() {
this.listeners.forEach((listener) => listener());
}
addListener(listener: Listener) {
this.listeners.add(listener);
}
removeListener(listener: Listener) {
this.listeners.delete(listener);
}
}Store
useDispatch
useSelector
Usage
CounterController.tsx
Counter.tsx
Last updated