【源码学习】redux-thunk

释放双眼,带上耳机,听听看~!

阅读 redux 源码之后,想要加深一下对中间件的理解,于是选择 redux-thunk(2.3.0)这个源码只有十几行的中间件。

之前 redux 的学习笔记 https://www.cnblogs.com/wenruo/p/9664375.html

redux 中的 applyMiddleware.js

export default function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args)
    let dispatch = () => {
      throw new Error(
        `Dispatching while constructing your middleware is not allowed. ` +
          `Other middleware would not be applied to this dispatch.`
      )
    }

    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    dispatch = compose(...chain)(store.dispatch)

    return {
      ...store,
      dispatch
    }
  }
}

 

每个中间件需要传入 store(只有 getState 和 dispatch)和 next(由上一个中间处理过的 dispatch)

在生成 dispatch 的时候 传入的  middlewareAPI 中的 dispatch 是一个只抛出异常的函数,用来提示在创建 dispatch 的时候, 中间件不应该使用 dispatch 。

创建后又将 dispatch 赋值为经过中间件生成的函数。这时

const middlewareAPI = {
    getState: store.getState,
    dispatch: (...args) => dispatch(...args)
}

中 middlewareAPI.dispatch 就变成了最新的 dispatch 所以在中间件中可以使用 dispatch、

 

接下来可以看 redux-thunk 的源码

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;

使用时可以是 applyMiddleware(thunk) 或者 applyMiddleware(thunk.withExtraArgument(api)) 

如果是默认的 thunk 那么中间件的函数为

const thunk = ({ dispatch, getState }) => next => action => {
if (typeof action === \'function\') {
        return action(dispatch, getState);
    }

    return next(action);
};

如果是函数 就传入 dispatch 和 getState 否则就执行默认的 next 

let store = createStore(reducer, applyMiddleware(thunk));
let action = (dispatch) => {
    ajax(options).then((res) => {
        dispatch({ type: \'change\', content: res.data });
    })
}
store.dispatch(action);

这样对于异步的操作就可以在 redux 中使用了~

 

人已赞赏
随笔日记

如何从小白到合格的区块链工程师:写在前面的一些话

2020-11-9 3:51:57

随笔日记

Unix历史及相关概念回顾

2020-11-9 3:51:59

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
购物车
优惠劵
今日签到
有新私信 私信列表
搜索