Redux中间件原理

2019-01-30  本文已影响0人  sarah_wqq

Redux提供了非常强大的数据流管理功能,是一个可预测的状态容器,解决数据在 React 应用中的流动方式及过程

1.原理

Redux 的中间件提供的是位于 action 被发起之后,到达 reducer 之前的扩展点,这种机制可以让我们改变数据流,实现如异步 action ,action 过滤,日志输出,异常报告等功能。

原redux的数据流:view -> action -> reducer -> store

数据流.png

加上中间件后变成了: view -> action -> middleware -> reducer -> store


image.png

2.接口

createStore函数接收参数为(reducer, [initState], enhancer)

import {createStore, applyMiddleware} from 'redux';
import thunkMiddleware from 'redux-thunk';
import rootReducer from '../reducers';
import defaultState from './defaultState';

export default function configureStore() {
    let store = createStore(
        rootReducer,
        defaultState,
        applyMiddleware(
            thunkMiddleware
        )
    );
    return store;
}

enhancer是一个组合 StoreCreator 的高阶函数, 返回的是一个新的强化过的 StoreCreator,再执行StoreCreator就能得到一个加强版的 store。
例子中enhancer即为applyMiddleware,从下面的源码可知,applyMiddleware 改写了 store 的 dispatch 方法,新的 dispatch 即是被所传入的中间件包装过的。

applyMiddleware 的源码:

export default function applyMiddleware(...middlewares) {
  return createStore => (...args) => {
    const store = createStore(...args)
    let dispatch = () => {
      throw new Error(
      )
    }
    const middlewareAPI = {
      getState: store.getState,
      dispatch: (...args) => dispatch(...args)
    }
    const chain = middlewares.map(middleware => middleware(middlewareAPI))
    // 将不同的 middlewares 一层一层包裹到原生的 dispatch 之上
    // compose 将 chain 中的所有函数组装成一个新的函数,即新的 dispatch
    dispatch = compose(...chain)(store.dispatch)
    return {
      ...store,
      dispatch
    }
  }
}

3.解读

例子1:
//一个啥都不干的中间件:
const doNothingMidddleware = (dispatch, getState) => next => action => next(action)

参数 dispatch 和 getState,分别代表着 Redux Store 上的两个同名函。然后中间件doNothingMidddleware 返回的函数接受一个 next 类型的参数,这个 next 是一个函数,如果调用了它,就代表着这个中间件完成了自己的职能,并将对 action 控制权交予下一个中间件。最后以 action 为参数的函数对传入的 action 对象进行处理,在这个地方可以进行操作,比如:

在具有上面这些功能后,一个中间件就足够获取 Store 上的所有信息,也具有足够能力可用之数据的流转。

例子2:

最出名的中间件 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;

redux-thunk 中间件的功能很简单。首先检查参数 action 的类型,如果是函数的话,就执行这个 action 函数,并把 dispatch, getState, extraArgument 作为参数传递进去,否则就调用 next 让下一个中间件继续处理 action 。

另外还有一些中间件如redux-logger(打印日志)、redux-promise(处理异步操作,但是返回Promise对象)、redux-saga等

上一篇 下一篇

猜你喜欢

热点阅读