目录

手写简易Redux

简易发布订阅模式

上篇文章我们实现了发布订阅模式,这里再重现一次代码,写法更简洁一些

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。回调函数列表的触发不再区分事件类型。

Redux完善

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方法来实现。