重写一个简易的redux状态管理工具

1. redux中三个常见的方法

  • getState(),用来获取state对象树
  • dispatch(),分发同步action
  • subscribe(),绑定监听,当state树中某些属性发生改变的时候,调用回调函数,重新渲染
/**
 * 首先,该函数的返回值是一个对象,因为在调用的时候都是 store.getState(),所以返回的对象中有是三个属性的属性值必然是函数
 */
export function createStore(reducer) {
  let state  // 保存state对象树
  const listeners = []  // 保存所有的subscribe的回调函数
  state = reducer(state, {type: '@mini'})
  function getState() {
    return state
  }
  
  function dispatch(action) {
    // 将reducer函数得到的新的state数替换掉原来的state
    state = reducer(state, action)
    // 将所有subscribe的回调函数调用,来达到重新渲染的效果
    listeners.forEach(listener => {
      listener()
    })
  }
  // 将所有的调用subscribe的回调函数保存起来,当调用dispatch改变属性状态时,将所有subscribe的回调函数调用,来达到重新渲染的效果
  function subscribe(listener) {
    listeners.push(listener)
  }
  return {getState, dispatch, subscribe}
}

2.redux库中第二个重要的东西,整合多个reducer的函数(combinReducers)

需要注意的是:整合所有 reducer 的函数,他自己本身还是一个 reducer。所有该函数的返回值就是一个 reducer函数
代码:

export function combineReducers(reducers) {
  
  // 因为返回的是一个reducer函数,所以该函数存在 state 和 action 的参数,其中 state为总的 state 树,action 为 dispatch传入的 action
  /**
   * state = {
   *   count: 0,
   *   msgs: []
   * }
   */
  return function (state = {}, action) {
    // 因为处理每个reducer函数,返回的值都是该reducer函数的新的state,那么最后所有的子state就要组成一个新的state树,该对象就是用来保存最后返回的新的state总树
    const newState = {}
    // 因为传入 combineReducers 的是一个对象,且每个属性的属性值都是一个以属性名来命名的reducer函数,所有key通过遍历得到所有的键名,每个键名也就是每一个reducer的函数名
    const keys = Object.keys(reducers)
    // 再遍历该键名组成的数组
    keys.forEach(key => {
      // 找到每一个子的reducer函数
      const childReducer = reducers[key]
      // 因为每个函数都是一个reducer函数,所有需要一个 state对象和一个同步 action,同步 action是用户传入的,而子state就是总state上的一个属性
      const childState = state[key]
      // 调用子reducer函数,返回的结果是一个新的子state
      const newChildState = childReducer(childState, action)
      // 将新的子state存入最后需要返回的新的总state中
      newState[key] = newChildState
    })
    return newState
  }
}

将上面的代码简化一下:

export function combineReducers(reducers) {
  
  return function (state = {}, action) {
    return Object.keys(reducers).reduce((newState, reducerName) => {
      newState[reducerName] = reducers[reducerName](state[reducerName], action)
      return newState
    }, {})
  }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值