一步步带你解读redux源码

栏目: IOS · Android · 发布时间: 4年前

内容简介:那么我们再来看看createStore这个api,可以看到上述例子有这么一段代码,我们知道createStore 是一个函数,并且他返回了一个对象store,也就是我们常说的存储状态的仓库如下图,现在让我们继续深入下去,可以看到createStore这个函数接收三个参数,那么这时候我们心里肯定在想三个参数分别干嘛用的呢?我们先把它们列出来,在逐一分析每个参数的含义写了这么多,首先我们来看看他的第一个api,store.getState()
  • Redux 是 JavaScript 状态容器, 提供可预测化的状态管理。redux 其实说白就是一个状态管理存储
一步步带你解读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})
  })
复制代码
  • 可以看看上面例子

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

    • 1、createStore
    • 2、getState
    • 3、dispatch
    • 4、subscribe
  • 这是github上的源码目录,目录文件不是很多,第一篇首先分析的是入口redux的createStore.js

    一步步带你解读redux源码

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

let store = createStore(reducer)
 let state = store.getState()
复制代码
  • 现在点进去看createStore.js,滑到源码最底端,可以清晰的看到createStore方法暴漏出了五个api,前面三个是我们日常项目中常用的方法,看到这里,其实我们就能想到就是执行createStore方法时,会返回一个对象,这个对象上包含这五个属性。
    一步步带你解读redux源码

如下图,现在让我们继续深入下去,可以看到createStore这个函数接收三个参数,那么这时候我们心里肯定在想三个参数分别干嘛用的呢?我们先把它们列出来,在逐一分析每个参数的含义

  • reducer
  • preloadedState
  • enhancer
一步步带你解读redux源码
  • 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()方法 返回一个状态

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

currentState状态是如何获取的呢?

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

那第二个问题要考虑的就是在哪里改变这个状态的呢,因为我们在项目中可是有需求想要去改变状态的,而不只是存着它们,当祖宗一样供着,那样消耗也会很大...现在让我们继续追踪,redux 到底是如何进行状态的改变?

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

如上述例子,可以看到源码中这么一段代码,我进行简单的删减,只留下了这三行代码,从这三行代码我们就可以看出来很多问题。

  • 首先可以看出currentState是在dispatch方法里执行然后进行获取值的,并且dispatch接收一个action函数
  • 这就可以得出我们改变状态的唯一途径是必须出发一个action 也即是执行dispatch(action)这个方法,稍后我们在解读dispatch
  • 然后currentState 是执行currentReducer(currentState, action)这个方法之后返回的值?
  • 那么这个currentReducer(currentState, action)又是干嘛的呢?

以上所述就是小编给大家介绍的《一步步带你解读redux源码》,希望对大家有所帮助,如果大家有任何疑问请给我留言,小编会及时回复大家的。在此也非常感谢大家对 码农网 的支持!

查看所有标签

猜你喜欢:

本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们

JavaScript实战

JavaScript实战

Frank W. Zammetti / 张皛珏 / 人民邮电出版社 / 2009-8 / 59.00元

随着Ajax的兴起,JavaScript迅速地从改进网站的配角晋升为开发专业级高质量应用的主角,成为了Web开发中不可缺少的一员。 本书主要通过10个具体项目,包括构建可扩展的JavaScript库、使用GUI窗口小部件框架、开发支持拖放的购物车和编写JavaScript游戏等,讲述JavaScript最佳实践、Ajax技术,以及一些流行的JavaScript库,如Rico、Dojo、scr......一起来看看 《JavaScript实战》 这本书的介绍吧!

图片转BASE64编码
图片转BASE64编码

在线图片转Base64编码工具

Base64 编码/解码
Base64 编码/解码

Base64 编码/解码