Redux源码阅读_1(上)

前言

看完 Redux文档,对Redux的内部运作不是很了解,大致问题记录如下:

  • 容器组件怎么通过connect将store里的数据传入展示型组件的props中?
  • mapStateToProps与mapDispatchToProps怎么将state与dispatch的值组装到props?
  • action是什么?dispatch action做了些什么操作?
  • 若dispatch 一个函数,则函数默认参数有dispatch与state,自定义的函数怎么能默认接受这两个参数的?

带着这些问题打开Redux源码,发现才一年的时间没做前端,Redux源码都从js换成ts了,屁颠屁颠跑去看TS文档,没咋看懂,但是应该能上源码了。

源码结构

首先看看文件夹目录结构


src

几个常用的api都在src/下,再下一级目录就是封装的一些类型,这些后面再详细描述,先开始上源码!

index.ts

这个文件主要导出了一些常用的接口

import createStore from './createStore'
import combineReducers from './combineReducers'
import bindActionCreators from './bindActionCreators'
import applyMiddleware from './applyMiddleware'
import compose from './compose'
import warning from './utils/warning'
import __DO_NOT_USE__ActionTypes from './utils/actionTypes'

//中间省略一些代码
···
export {
  createStore,
  combineReducers,
  bindActionCreators,
  applyMiddleware,
  compose,
  __DO_NOT_USE__ActionTypes
}

可以看到我们Redux里常用的api,createstore、combineReducers、applyMiddleware、compose都给导出了,bindActionCreators之前没有用到过,正好可以看一下实现和用法。

按照导出顺序挨个看看这些文件

createStore.ts

这个文件重载了两个createStore方法,主要区别是有无 preloadedState 这个参数。

export default function createStore<
  S,
  A extends Action,
  Ext = {},
  StateExt = never
>(
  reducer: Reducer,
  enhancer?: StoreEnhancer
): Store, A, StateExt, Ext> & Ext
export default function createStore<
  S,
  A extends Action,
  Ext = {},
  StateExt = never
>(
  reducer: Reducer,
  preloadedState?: PreloadedState,
  enhancer?: StoreEnhancer
): Store, A, StateExt, Ext> & Ext

用UML画了个假装是createStore的类图,主要是为了方便看这个函数里面定义的一些属性和方法。


假装是createStore的类图

函数申明

export default function createStore<
  S,
  A extends Action,
  Ext = {},
  StateExt = never
>(
  reducer: Reducer,
  preloadedState?: PreloadedState | StoreEnhancer,
  enhancer?: StoreEnhancer
): Store, A, StateExt, Ext> & Ext

这个函数接收两到三个参数,其中,若只传入两个参数,且第二个参数为函数,会把第二个参数preloadedState赋值给enhancer,然后preloadedState赋值为undefined。

if (
    (typeof preloadedState === 'function' && typeof enhancer === 'function') ||
    (typeof enhancer === 'function' && typeof arguments[3] === 'function')
  ) {
    throw new Error(
      'It looks like you are passing several store enhancers to ' +
        'createStore(). This is not supported. Instead, compose them ' +
        'together to a single function.'
    )
  }
// 这里,其他都是类型检测
  if (typeof preloadedState === 'function' && typeof enhancer === 'undefined') {
    enhancer = preloadedState as StoreEnhancer
    preloadedState = undefined
  }

  if (typeof enhancer !== 'undefined') {
    if (typeof enhancer !== 'function') {
      throw new Error('Expected the enhancer to be a function.')
    }

    return enhancer(createStore)(
      reducer,
      preloadedState as PreloadedState
    ) as Store, A, StateExt, Ext> & Ext
  }

  if (typeof reducer !== 'function') {
    throw new Error('Expected the reducer to be a function.')
  }

然后就是方法内其他函数的介绍

dispatch(action)

该方法主要做了如下三个操作:
1、修改 isDispatching的值(定义这个有点类似于锁的思想,阻止其他操作的修改)。
2、计算属性currentState的值,该值通过getState()方法获取
3、执行listeners[]数组里的每个listener方法。
4、返回action(这个action为函数传入的action)

代码如下:

function dispatch(action: A) {
    if (!isPlainObject(action)) {
      throw new Error(
        'Actions must be plain objects. ' +
          'Use custom middleware for async actions.'
      )
    }

    if (typeof action.type === 'undefined') {
      throw new Error(
        'Actions may not have an undefined "type" property. ' +
          'Have you misspelled a constant?'
      )
    }

    if (isDispatching) {
      throw new Error('Reducers may not dispatch actions.')
    }

    try {
      isDispatching = true
      currentState = currentReducer(currentState, action)
    } finally {
      isDispatching = false
    }

    const listeners = (currentListeners = nextListeners)
    for (let i = 0; i < listeners.length; i++) {
      const listener = listeners[i]
      listener()
    }

    return action
  }

下接Redux源码阅读_1(下))

你可能感兴趣的:(Redux源码阅读_1(上))