上篇文章我们实现了发布订阅模式,这里再重现一次代码,写法更简洁一些
function createEventHub() { const map = {} return { on(type, handler) { map[type] = (map[type] || []).concat(handler) }, fire(type, data) { map[type] && map[type].forEach(handler => handler(data)) } } } let EventHub = createEventHub() EventHub.on('hello', data => console.log(data)) EventHub.fire('hello', 'jirengu.com')
改造发布订阅实现Redux雏形
function createStore(initState) { let state = initState let handlers = [] return { getState() { return state }, changeState(newState) { state = newState handlers.forEach(handler => handler()) }, subscribe(handler) { handlers.push(handler) } } } let store = createStore({msg: 'jirengu'}) store.subscribe(() => { let state = store.getState() console.log(state) }) store.changeState({msg: '饥人谷'})
以上代码依然是发布订阅模式,只不过把 on 换成了 subscribe,把 fire 换成了 changeStage。回调函数列表的触发不再区分事件类型。
function createStore(reducer) { let state let handlers = [] return { getState() { return state }, dispatch(action) { state = reducer(state, action) handlers.forEach(handler => handler()) }, subscribe(handler) { handlers.push(handler) } } } function counter(state = 10, action) { switch (action.type) { case '+': return state + action.val case '-': return state - action.val default: return state } } let store = createStore(counter) store.subscribe(() => console.log(store.getState())) store.dispatch({type: '+', val: 10}) store.dispatch({type: '-', val: 10})
把直接通过 changeState 修改状态改成通过 dispatch 一个 action 来触发,把state的修改规则通过调用createStore传递的reducer方法来实现。