深入浅出解读redux源码之createStore、combineReducers

在react中使用redux状态管理的一个完整的流程:

0.使用中间件创建仓库,并且通过react-redux中的Provider 传入仓库,以便子组件连接仓库,获取状态和派发动作。
1.先构建一个组件
2.实现页面的基本布局和css样式
3.根据后台文档写好调取api的方法,比如axios/fetch 以及使用resful风格
4.在action-types.js文件中定义新的动作类型 并导出
5.在action里添加新的方法,调取后台接口,获取后台数据,并通过payload传参。如果需要发给后台参数,通过getState结构出来,在调取接口的时候处理好并传给后台。
6.在自己的reducer中增加case以处理相应的动作类型
7.组件通过connect连接仓库,并在组件种调用action方法,获取数据处理逻辑
说明:1.派发动作会自动执行renducer,然后把action当做参数传进去,执行。

那么redux内部究竟是如何创建仓库?如何进行状态管理呢?

创建仓库

首先,redux是一种设计模式,可以和jQuery/原生js/react一起使用。本文配合使用的是原生js。

//创建仓库
const createStore =(reducer)=>{
  let state;
  let listeners=[];
  let getState=()=>state;
//dispatch做了什么?
//1.每派发一个动作,就会执行reducer合并老状态,返回一个新状态
//2.让订阅的函数执行,如果订阅的是render函数就会重新渲染页面
  let dispatch=(action)=>{
    state=reducer(state,action);//当仓库中的state发声改变,会重新执行render,读取最新的状态树并更新视图
    listeners.forEach(l=>l());
  }
// 订阅函数
  let subscribe=(listener)=>{
    listeners.push(listener);
    return ()=>{//返回一个取消订阅的函数,这个函数手动执行了,才会取消订阅
      listeners.filter(l=>l!=listener);
    }
  }
  return {
    getState,//获取仓库状态
    subscribe,//订阅
    dispatch//派发动作,发布订阅的事情
  }
}
export {createStore}

如何取消订阅?

let unsubscribe=store.subscribe(render);//假设订阅的是render函数

setTimeout(()=>{
  unsubscribe();
},5000)
  //取消订阅之后 也就是5s之后派发动作页面不会重新渲染


----------

`一般在react的生命周期的组件将要挂载和组件将要卸载两个阶段进行订阅和取消订阅。`

componentWillMount(){
  this.unsubscribe=store.subscribe(()=>{
   //订阅的函数可以是render
  })
}

componentWillUnMount(){
  this.unsubscribe();
}

combineReducers: 让每个小管理员执行,更新每一个小的状态树

let combineReducers = (reducers)=>{
    return function (state = {}, action) {
        return Object.keys(reducers).reduce((newState, key) => {
            newState[key] = reducers[key](state[key], action);
            return newState;//返回更新后的state
        }, {});
    }
}
------解读这段代码如下:----
// 假设大的管理reducers是这样的:
let reducers={home:小管理员fn1,list:小管理员fn2,detail:小管理员fn3};

Object.keys(reducers) -> [home,list,detail] //把属性名取出来作为一个数组

[home,list,detail].reduce((newState,key)=>{

      解读此行代码 newState[key] = reducers[key](state[key], action);
      
      newState = { home/list/detail: 新的state }   
      新的state= 小管理员reducer分别执行
                fn1/fn2/fn3(state.home/list/detail,action)执行,
                执行的参数是老是state和派发的动作,更新每个小的状态树
                
  return newState ;//返回更新后的状态树
 },{})//第一个参数是空对象作为newState的值

本文将会深入分析redux源码的实现,未完待续,敬请关注。。。

相关推荐