ReactNative|ReactNative Redux中间件 redux-thunk

参考 : 理解redux-thunk
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是作为redux的 middleware 存在的,用法和普通 middleware 的用法是一样的,注册 middleware 的代码如下:
import thunk from 'redux-thunk' const store = createStore(reducer, applyMiddleware(thunk))

注册后可以这样使用:
// 用于发起登录请求,并处理请求结果 // 接受参数用户名,并返回一个函数(参数为dispatch) const login = (userName) => (dispatch) => { dispatch({ type: 'loginStart' }) request.post('/api/login', { data: userName }, () => { dispatch({ type: 'loginSuccess', payload: userName }) }) } store.dispatch(login('Lucy'))

PS : login本身是一个嵌套函数, 返回值是一个函数, 所以 login('Lucy') 返回的就是一个函数, 所以这里就是dispatch(function)
可以看到,redux-thunk主要的功能就是可以让我们dispatch一个函数,而不只是普通的 Object。后面我们会看到,这一点改变可以给我们巨大的灵活性。
了解了如何使用,接下来我们看一下它的实现原理。
起源 redux-thunk的代码和原理非常简单,但我觉得难的部分是为什么需要这样一个库。关于redux-thunk的起源可以看一下 Redux 001 号的 issue: How to dispatch many actions in one action creator[1]
ReactNative|ReactNative Redux中间件 redux-thunk
文章图片
image.png 大概意思就是问如何一次性发起多个 action,然后作者回答我可以让 actionCreator 返回一个函数。然后相关的 PR 如下: fix issue 001[2]
ReactNative|ReactNative Redux中间件 redux-thunk
文章图片
image.png 为什么需要? 现在我们理解了redux-thunk可以让我们 dispatch 一个 function,但是这有什么用呢?其实我觉得这是一项基础设施,虽然功能简单,但可扩展性极其强大。
比如很多时候我们需要在一个函数中写多次 dispatch。这也是上面 issue 中提到的问题。比如上面我们示例代码中,我们定义了 login 函数做 API 请求,在请求发出前我们可能需要展示一个全局的 loading bar,在请求结束后我们又需要将请求结果存储到 redux store 中。这都需要用到 redux 的 dispatch。
当然在一个函数中写多个 dispatch 只是我们可以做的事情之一,既然它是一个 function,而且并不要求像 reducer 一样是 pure function,那么我们可以在其中做任意的事情,也就是有副作用(side effect)的事情。
简单粗暴的总结 1 .如果我们的需求中, 想要在一个函数中做多次dispatch, 并且相互有关联, 如嵌套函数的方式, 那就可以使用thunk解决这个需求.
  1. 普通的redux中, dispatch(object), thunk中 dispatch(function)
实例 注册
import { createStore, applyMiddleware } from 'redux'; import thunks from 'redux-thunk'; import getReducers from '../Reducers'; export default function getStore() { return createStore( getReducers(), applyMiddleware(thunks, logger) ); }

创建函数
/** * 检查手机网络 */ export const checkNetwork = () => { return async (dispatch) => { // 获取网络状态 const netConnectStatus = await NetworkUtils.checkNetworkConnected(); if (!netConnectStatus) { dispatch({ type: UPDATE_NETWORK_ERROR_DIALOG, showNetworkErrorDialog: true }); } }; };

(某个Page初始化)调用时机
componentDidMount() { this.props.dispatch(checkNetwork()); }

总结 【ReactNative|ReactNative Redux中间件 redux-thunk】简单粗暴理解为:
  1. ReactNative Redux flow是同步数据处理
  2. redux-thunk是异步数据处理, 也就是异步处理+Redux
3.这样做的好处就是把所有的业务逻辑封装在action里面.. 某一个页面的page在componentDidMount只需要调一个方法就可以了. 代码管理起来就简洁很多了

    推荐阅读