Redux 源码解析

闲谈

好些个日子没有写博客了,脑子里头想着有好些事情该干的该写的,但平日里就又陷入实验室与课程所带来无穷的琐事中了。偶尔偷得闲,还是写两篇罢,老是囤在笔记里头日晒不着的,眼瞅着就要发霉生虫了。

Redux

Redux源码的设计简介明白,拢共加起来也不到千行,注释写的也清清楚楚,只要心里头对于Redux的设计理念有个大致的了解,源码就能很轻松的阅读。

Redux 是 JavaScript 状态容器,提供可预测化的状态管理。
Redux 由 Flux 演变而来,但受 Elm 的启发,避开了 Flux 的复杂性。

官网的这两句介绍就把Redux的来龙去脉介绍的一清二楚了,要理解Redux的设计思路,首先得对Redux的核心概念和函数式编程思想有一定的认知。
这儿就不对这些预备知识进行介绍了,Redux文档中已经给出了非常细致的介绍(其实Redux文档中涵盖了方方面面的介绍,例如核心思想、使用技巧、API文档等,这些内容比单单分析Redux源码更有价值)。函数式编程在Redux源码中大概体现在Currying、Compose以及纯函数,只需花10分钟简单了解即可。

Redux 源码结构

首先来看一眼Redux源码的文件结构:
Redux源码文件结构
文件结构很清爽,包含了6个核心文件和3个工具文件,简单列个表来看看其大致功能:

文件 功能 备注
index.js 入口文件
createStore.js 提供 createStore API
compose.js 函数组合 虽然也是工具文件的功能但是不知道为什么不放在 utils 目录下
combineReducers.js 提供了 combineReducers API,同时包含了一些 reducer 的验证函数
bindActionCreators.js 提供了 bindActionCreators API
applyMiddleware.js 提供了 applyMiddleware API
warning.js 显示 warning 提示信息 工具文件
isPlainObject.js 判断对象是否是一个普通对象 工具文件
actionTypes.js 提供预设的 action 工具文件

工具函数

工程中所使用的工具文件包含在 utils文件夹下(compose.js也算在里头),简单介绍其中的一部分:

// compose.js

// Redux 中 compose 函数和函数式编程中是同个概念,就是对函数进行组合
// compose(f, g) --> f(g)
export default function compose(...funcs) {
   
  if (funcs.length === 0) {
   
    return arg => arg
  }

  if (funcs.length === 1) {
   
    return funcs[0]
  }

  return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
// actionTypes.js

const ActionTypes = {
   
  INIT: `@@redux/INIT${
     randomString()}`, // store 初始化所触发的 action
  REPLACE: `@@redux/REPLACE${
     randomString()}`, // store 中 reducer 被热替换所触发的 action
  PROBE_UNKNOWN_ACTION: () => `@@redux/PROBE_UNKNOWN_ACTION${
     randomString()}` // 未知的 action
}

actionTypes 中所定义的三个预设 action 主要在 createStore以及 combineReducers中有所使用,详见后续章节内容。

CreateStore

createStore是Redux所提供的API之一,其用于生成唯一的 store 并提供对应的 dispatchsubscribe等方法。Redux 中的 store 仅能通过 dispatch函数触发对应的 action 来改变,action 对应到纯函数的 Reducer 从而修改 store 的数据。createStore的一个使用示例如下:

let store = createStore(myReducer, {
   }, applyMiddleware(thunk, logger));

createStore接收三个参数:reducer, preloadedState, enhancer,其中reducer参数表示对store进行修改的 reducer 函数,其可由combineReducers函数组合多个 reducer 生成。preloadedState代表 store 的初始化状态,该参数可以省略,当其被省略时,输入参数为:reducer, enhancerenhancer是中间件通过applyMiddleware方法所生成的对createStore进行功能加强的函数。具体代码解析如下:

export default function createStore(reducer, preloadedState, enhancer) {
   
  // 处理传入多个 enhancer 的错误
  if (
    (typeof preloadedState === 'function' && typeof enhancer === 'function') ||
    (typeof enhancer === 'function' && typeof arguments[3] === 'function')
  ) {
   
    throw new Error('balabala')
  }

  // 当传入两个参数时,其输入参数的含义为 (reducer, enhancer)
  if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
   
    enhancer = preloadedState
    preloadedState = undefined
  }

  if (typeof enhancer !== 'undefined') {
   
    // enhancer 必须是一个函数
    if (typeof enhancer !== 'function') {
   
      throw new Error('Expected the enhancer to be a function.')
    }

    // 使用 enhancer 对 createStore 功能进行加强,enhancer 的具体执行功能见 applyMiddlerware
  
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值