一步步带你解读redux源码

小白带你一步步走入redux的源码(一、createStore)

  • Redux 是 JavaScript 状态容器, 提供可预测化的状态管理。redux 其实说白就是一个状态管理存储

- 下面是一个简单的计数器例子,这里写了一个增长减数字相加的问题
复制代码
<div id="counter">
      <div id="counterValue"></div>
      <button id="incrementBtn">+</button>
      <button id="decrementBtn">-</button>
  </div>
复制代码
  • 首先带你入门写个简单的使用的例子,下面这部分是JS的引用写法
// 引入了redux ,调用了createStore这个方法
  import {createStore} from "redux"
  let initState = 0;
  // 定义了两个独一无二的类型 Symbol 
  const INCREMENT = Symbol.for('INCREMENT')
  const DECREMENT = Symbol.for('DECREMENT')
  //  用来表示动做类型reducer接收两个参数,一个是状态,另一个是触发的行为
  // reduce 就是根据触发行为的不一样来返回对应的状态
  function reducer(state =initState ,action){
      console.log(action)
      switch(action.type){
          case INCREMENT:
              return state+1;
          case DECREMENT:
              return state-1;  
          default:
              return state;          
      }
  }
  // 新老状态对比而后生成新的状态
  let store = createStore(reducer)
  let state = store.getState()
  console.log(state)
  let counterValue = document.getElementById("counterValue")
  let incrementBtn = document.getElementById("incrementBtn")
  let decrementBtn = document.getElementById("decrementBtn")
  
  function render(){
      counterValue.innerHTML = store.getState()
  }
  // 能够手动订阅更新,也能够事件绑定到视图层。
  store.subscribe(render)
  incrementBtn.addEventListener("click",function(){
      console.log(1111)
      store.dispatch({type:INCREMENT,data:99})
      
  })
  decrementBtn.addEventListener("click",function(){
      store.dispatch({type:DECREMENT})
  })
复制代码
  • 能够看看上面例子git

  • 在上面的例子中咱们引入了redux ,其中运用了几个API,在上述例子中获得了引用,那么咱们能够来看看这几个api在源码是怎么样?是如何暴露出来的?github

    • 一、createStore
    • 二、getState
    • 三、dispatch
    • 四、subscribe
  • 这是github上的源码目录,目录文件不是不少,第一篇首先分析的是入口redux的createStore.js redux

那么咱们再来看看createStore这个api,能够看到上述例子有这么一段代码,咱们知道createStore 是一个函数,而且他返回了一个对象store,也就是咱们常说的存储状态的仓库api

let store = createStore(reducer)
 let state = store.getState()
复制代码
  • 如今点进去看createStore.js,滑到源码最底端,能够清晰的看到createStore方法暴漏出了五个api,前面三个是咱们平常项目中经常使用的方法,看到这里,其实咱们就能想到就是执行createStore方法时,会返回一个对象,这个对象上包含这五个属性。

以下图,如今让咱们继续深刻下去,能够看到createStore这个函数接收三个参数,那么这时候咱们内心确定在想三个参数分别干吗用的呢?咱们先把它们列出来,在逐一分析每一个参数的含义bash

  • reducer
  • preloadedState
  • enhancer

  • reducer相信你们很常见,它为了描述 action 如何改变 state tree , 就是处理action的reducer的处理函数, reducers是一个纯函数,接收参数state和action。只须要根据action,返回对应的state,并且必需要有返回。
function reducer(state =initState ,action){
            console.log(action)
            switch(action.type){
                case INCREMENT:
                    return state+1;
                case DECREMENT:
                    return state-1;  
                default:
                    return state;          
            }
        }
复制代码
  • preloadedState:这个就是初始化的状态state,能够传一个初始的值进来

看着这里,咱们就会想,createStore传入的的初始状态和reducer传入的初始状态哪一个优先级高?

  • enhancer:这个是createStore的加强器。你能够选择性的传入一个加强函 数取加强 store,例如中间件,时间旅行,持久化。这 redux 惟一一个自带的 加强器是的 applyMiddleware

写了这么多,首先咱们来看看他的第一个api,store.getState()并发

  • 经过store.getState()咱们能够获取store里面存储的状态,官方源码,能够看到只有短短十几行代码就实现了getState方法,而且返回了一个当前的状态currentState,
function getState() {
    if (isDispatching) {
      throw new Error(
        'You may not call store.getState() while the reducer is executing. ' +
          'The reducer has already received the state as an argument. ' +
          'Pass it down from the top reducer instead of reading it from the store.'
      )
    }
    return currentState
  }
复制代码

其实前面那个判断只是判断当reduce执行的时候不会进行获取状态,防止并发,若是把这个判断删掉,其实真正有用的就只有一行代码,也便是执行getState()方法 返回一个状态app

function getState() {
    return currentState
  }
复制代码

currentState状态是如何获取的呢?

  • 在源码中咱们只能够看到这一句话,而这个preloadedState是createStore里传入进来的, 因此若是当你没有执行触发action的行为以前,执行store.getState()直接获取的是传入的初始化状态
let currentState = preloadedState 
复制代码

那第二个问题要考虑的就是在哪里改变这个状态的呢,由于咱们在项目中但是有需求想要去改变状态的,而不仅是存着它们,当祖宗同样供着,那样消耗也会很大...如今让咱们继续追踪,redux 究竟是如何进行状态的改变?函数

function dispatch(action) {
    currentState = currentReducer(currentState, action)
    return action
  }
复制代码

如上述例子,能够看到源码中这么一段代码,我进行简单的删减,只留下了这三行代码,从这三行代码咱们就能够看出来不少问题。ui

  • 首先能够看出currentState是在dispatch方法里执行而后进行获取值的,而且dispatch接收一个action函数
  • 这就能够得出咱们改变状态的惟一途径是必须出发一个action 也便是执行dispatch(action)这个方法,稍后咱们在解读dispatch
  • 而后currentState 是执行currentReducer(currentState, action)这个方法以后返回的值?
  • 那么这个currentReducer(currentState, action)又是干吗的呢?

篇幅不易过长,下篇再继续写@--@ 创做不易,欢迎各位打赏@--@也能够关注本人公众号

相关文章
相关标签/搜索