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 Redux中间件 redux-thunk_第1张图片
image.png

大概意思就是问如何一次性发起多个 action,然后作者回答我可以让 actionCreator 返回一个函数。然后相关的 PR 如下: fix issue 001[2]

ReactNative Redux中间件 redux-thunk_第2张图片
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());
}

总结

简单粗暴理解为:

  1. ReactNative Redux flow是同步数据处理

  2. redux-thunk是异步数据处理, 也就是异步处理+Redux

3.这样做的好处就是把所有的业务逻辑封装在action里面.. 某一个页面的page在componentDidMount只需要调一个方法就可以了. 代码管理起来就简洁很多了

你可能感兴趣的:(ReactNative Redux中间件 redux-thunk)