Redux 스타일 Store 직접 구현
type Reducer<S, A> = (state: S, action: A) => S
type Listener<S> = (state: S) => void
interface Store<S, A> {
getState: () => S
subscribe: (listener: Listener<S>) => () => void
dispatch: (action: A) => A
}
function createStore<S, A>(
reducer: Reducer<S, A>,
preloadedState: S
): Store<S, A> {
let currentState: S = preloadedState
let listeners: Listener<S>[] = []
function getState(): S {
return currentState
}
function subscribe(listener: Listener<S>): () => void {
listener(currentState)
listeners.push(listener)
return function unsubscribe() {
listeners = listeners.filter((l) => l !== listener)
}
}
function dispatch(action: A): A {
currentState = reducer(currentState, action)
listeners.forEach((listener) => {
listener(currentState)
})
return action
}
return {
subscribe,
getState,
dispatch,
}
}
type Item = {
body: string
}
type State = {
items: Item[]
}
type Action = {
type: 'ADD'
payload: Item
}
const store = createStore<State, Action>(
(state, action) => {
switch (action.type) {
case 'ADD':
return {
...state,
items: state.items.concat(action.payload),
}
default:
return state
}
},
{
items: [],
}
)
store.subscribe((state) => {
console.log(state.items)
})
store.dispatch({
type: 'ADD',
payload: {
body: 'hello',
},
})