zoukankan      html  css  js  c++  java
  • 【源码学习】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 中使用了~

  • 相关阅读:
    【贪心 堆】luoguP2672 推销员
    【贪心 思维题】[USACO13MAR]扑克牌型Poker Hands
    「整理」[图论]最短路系列
    收集到的小玩意儿
    初遇构造函数
    在2440开发板液晶上显示两行字
    error: converting to execution character set: Invalid or incomplete multibyte or wide character
    宽字节
    宽字符wchar_t和窄字符char区别和相互转换
    linux获取文件大小的函数
  • 原文地址:https://www.cnblogs.com/wenruo/p/10239708.html
Copyright © 2011-2022 走看看