react学习笔记(四)异步action和redux中间件

456 阅读2分钟

什么是redux中间件

redux中间件其实是栓插在Action和Reducer之间的一个函数,可以拿到getState和dispatch,在dispatch Action的时候可以处理一些其他的事情,可以理解成dispatch增强器

如何使用中间件呢?

redux对外提供了applyMiddleware方法来使用中间件

import { applyMiddleware } from 'redux'

const store  = createStore(
    reducer,
    applyMiddleware(yourMiddleWare)
)

redux中间件用的比较多的就是redux-thunk和redux-suga,作用就是用来解决异步action的问题,这里主要说一下redux-thunk

redux-thunk

redux-thunk是一个dispatch增强器,通过对store的dispatch方法的修改,使其支持具有处理异步action的能力

首先来看一下异步action的写法

const asyncAction = ()=>{
    return (dispatch)=>{
       setTimeout(()=>{
           dispatch({
               type:'Test1'
           })
           dispatch({
               type:'Test2'
           })
       },1000) 
    }
}

store.dispatch(asyncAction())

不难看出,异步action是一个function,接受dispatch参数,在这个function里面可以进行任意的异步操作,可以dispatch多个action

而redux默认提供的dispatch是无法处理这种形式的action的,redux-thunk就是让dispatch支持这种action,如何使用呢?很简单!

import thunk from 'redux-thunk'
const store = creatStore(reducer,applyMiddleware(thunk))

如此就可以愉快的使用异步action了。

那么问题来了,redux-thunk怎么就能让dispatch支持这种形式的异步action呢?首先,我们来看看一个基本的redux中间件是如何组成的

const myMiddleWare = ({getState,dispatch})=>{
    return (next)=>{
        return (action)=>{
            //do something
            return next(action)
        }
    }}

它是一个层层返回的function,可以劫持到发往reducer的action,然后执行一些自定义的操作,最后再返回next(action),这里的next(action)会执行下一个中间件,并把当前的action传入.借此我们可以自己猜想一下:

const myMiddleWare = ({getState,dispatch})=>{
    return (next)=>{
        return (action)=>{
            //如果过来的action是一个function,就调用它,并把dispatch传入,否则就走下一个中间件
            if(typeof action === 'function'){
                action(dispatch)
            }else{
                return next(action)
            }
        }
    }
}

就这么几行,也可以简陋的实现redux-thunk的处理异步action的功能,我们再看看它的源码

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;

惊讶的发现,redux-thunk的实现与我们猜想的大概一致,只是它对外暴露了一个支持传参的中间件api,传入的参数作为一异步action的第三个参数回传

至此,相信大家对redux的中间件以及异步action已经有了一些基本的认识了