Redux源码系列-Redux-thunk源码分析

#理解什么是中间件

https://github.com/zp1112/blog/issues/11

thunk中间件

  • 先看中间件如何使用生效的
  • index.js
import {Provider} from 'react-redux'
import storeData from './reducerfile/index.js'
import {createStore, applyMiddleware} from 'redux'
import thunk from 'redux-thunk'

const store = createStore(storeData, applyMiddleware(thunk))

ReactDOM.render(
     
        
    , 
    document.getElementById('root')
)
  • action.js
export const fetchData = () => (dispatch) => {
  dispatch(change(9999, 6666))
  setTimeout(() => {
    getApi().then(data => {
      console.log(data)
      dispatch(change(data.age, data.text))
    })
  },1000)
}

发现就是原来单纯对象的action,注入了重写后的dispatch,进而在这个action 中可以做其他操作
  • 在redux使用中间件以后,重写了dispatch
在组件中调用: dispatch(action) = middleware(store)(store.dispatch)(action) //
  • 在用applyMiddleware时,实现重写dispatch代码
  • applyMiddleware的主要作用就是传给中间件store,dispatch,还有根据不同的中间件重写dispatch
export function applyMiddleware(middleware) { // 
  return createStore => (...args) => {
    const store = createStore(...args)
    let dispatch = store.dispatch

    const midApi = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args) // 原生的dispatch
    }
    dispatch = middleware(midApi)(store.dispatch) //注意这里重写了dispatch的同时也保存了原生的dispatch传给中间件
    return {
      ...store,
      dispatch //这里的dispatch已经被改写了
    }
  }
}
  • 中间件,其实现原理
const thunk =(store) => next => action =>{}
// 这里取到的dispatch是改写后的dispatch,next等价于原生的dispatch
const thunk = ({ dispatch, getState }) => next => action => {
  if (typeof action === 'function') {
    return action(dispatch, getState)
//这里的dispatch是等价于 middle(store)(store.dispatch)(action)
  }
  return next(action) //返回不是函数,就按照没有中间件的时候,直接dispatch操作
// 注意这里的next等价于原生的store.dispatch
}

由上面可以知道中间件要获得store才行
所以applyMiddleware

function middleware({midApi}){
    return function(dispatch){
        return function(action){
            action(dispatch)
        }
    }
}
function action(dispatch){
    dispatch(action)
    const data = await getData()
    dispatch({type: 'DO',payload: data})
    
}
// action 为function
dispatch(action)  // 等价于下面
middleware(midApi)(dispathc)(action()) // 执行action(dispatch)
因为运用中间件的时候已经将dispath重新赋值了

export function applyMiddleware(middleware) {
    // 
    return createStore => (...args) => {
    // 关键步骤,通过createStore得到一个store对象
   // store对象有dispatch和getState方法
      const store = createStore(...args)
      let dispatch = store.dispatch
  
      const midApi = {
        getState: store.getState,
        dispatch: (...args) => dispatch(...args)
      }

      // 以后执行dispatch,就是执行middleware(midApi)(store.dispatch)
      dispatch = middleware(midApi)(store.dispatch)
      return {
        ...store,
        dispatch
      }
    }
  }


thunk(midApi)(dispathc)(action()) // 执行action(dispatch)

关键:

  • applyMiddleWare获取到了createStore方法
  • createStore()执行返回一个对象,包含了dispatch和getState
    于是讲dispathc被重新赋值为middleware(midApi)(store.dispatch),以后调用:
dispatch(action) //等价于
middleware(midApi)(store.dispatch)(action)

applyMiddleWare为什么能够调用createStore方法,并且createStore()返回一个对象,返回的对象包含什么?
看createStore部分源码

  • createStore部分源码
export default function createStore(reducer, preloadedState, enhancer) {
 
  let currentReducer = reducer 
  let currentState = preloadedState /
  let isDispatching = false 

// 所以上面
  export {
    dispatch, 
    subscribe,
    getState, 
    replaceReducer,
    [$$observable]: observable
  }
  
}



由createStore源码中,暴露出了dispatch和getState方法所以applyMiddleware中能够拿到dispatch和getState
为什么能够获取createStore方法

export default function createStore(reducer, preloadedState, enhancer) {
  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
    preloadedState = undefined
  }

  if (typeof enhancer !== 'undefined') {
    if (typeof enhancer !== 'function') {
      throw new Error('Expected the enhancer to be a function.')
    }
    
    // 这里的enhancer就是上面的applyMiddleware
    // enhance函数立马调用的createStore就传入进去了
    return enhancer(createStore)(reducer, preloadedState)
  }
 .........
}

你可能感兴趣的:(react)