redux-thunk源码分析

Redux Thunk是一个redux的thunk中间件,项目源码gaearon/redux-thunk

所谓thunk函数,就是”传名调用”的一种实现策略,实现惰性求值。

// calculation of 1 + 2 is immediate
// x === 3
let x = 1 + 2;

// calculation of 1 + 2 is delayed
// foo can be called later to perform the calculation
// foo is a thunk!
let foo = () => 1 + 2;

我在没有使用x的时候,1+2就已经被计算完了,而foo只有被调用时,foo()才是3.


在使用redux的时候,我们可能会使用发两种action。

const INCREMENT_COUNTER = 'INCREMENT_COUNTER';

function increment() {
  //正常的action
  return {
    type: INCREMENT_COUNTER
  };
}

//thunk action creators
function incrementAsync() {
  //特殊
  return dispatch => {
    setTimeout(() => {
      // Yay! Can invoke sync or async actions with `dispatch`
      //异步action
      dispatch(increment());
    }, 1000);
  };
}

正常的actionCreator返回的action是对象,正常会dispatch出去。
而特殊情况下返回的是fuction,无法dispatch的,比如网络请求之后无法发出action。
而redux-thunk很巧妙的根据返回的类型,如果是function,就把dispatch和getState作为参数传入了回调函数,在回调函数中完成了dispatch。
这样就可以在actionCreator里return一个回调函数。

function createThunkMiddleware(extraArgument) {
  return ({ dispatch, getState }) => next => action => {
    if (typeof action === 'function') {
      return action(dispatch, getState, extraArgument);
    }

    return next(action);
  };
}

const thunk = createThunkMiddleware();
thunk.withExtraArgument = createThunkMiddleware;

export default thunk;