前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >redux-thunk引发的redux middleware和store enhancer浅析

redux-thunk引发的redux middleware和store enhancer浅析

作者头像
IMWeb前端团队
发布2019-12-03 18:07:11
1.1K0
发布2019-12-03 18:07:11
举报
文章被收录于专栏:IMWeb前端团队

本文作者:IMWeb EnjoyChan 原文出处:IMWeb社区 未经同意,禁止转载

项目中使用redux-thunk来解决异步请求的问题,但是为什么要引入redux-thunk来解决异步请求问题,不借助redux-thunk就无法解决吗?

代码语言:javascript
复制
以setTimeout dispatch场景为例,在异步执行时dispatch action就可以实现了

// 1

store.dispatch({

  type: 'BEFORE_ASYNC'

})

setTimeout(() => {

  store.dispatch({

    type: 'DOING_ASYNC'

  })

}, 0)

既然可以简单两步解决,那么为什么还需要引入redux-thunk, 或者说redux-thunk可以解决什么场景问题;来看下面这个场景,我们上面那份代码可能被多次调用,根据传入参数来执行,于是我们封装一个函数:

代码语言:javascript
复制
// 2

function encapsulateFunc(dispatch, data) {

  dispatch({

    type: 'BEFORE_ASYNC'

  })



  setTimeout(() => {

    dispatch({

      type: 'DOING_ASYNC',

      data

    })

  }, 0)

}

// 调用
encapsulateFunc(store.dispatch, {data: '2'});

第二种

代码语言:javascript
复制
// 3

// 传入依赖
import store from './store';

function encapsulateFunc(data) {

  store.dispatch({

    type: 'BEFORE_ASYNC'

  })



  setTimeout(() => {

    store.dispatch({

      type: 'DOING_ASYNC',

      data

    })

  }, 0)

}

// 调用
encapsulateFunc({data: '3'});

对比上面封装函数的两种方法我们可以看出:

  1. 第一种方法, 每次调用的时候都传入dispatch参数,十分冗余
  2. 第二种方法,植入store依赖,方法依赖于store,这使得代码的迁移性并不友好

鉴于上述,我们再来看看使用redux-thunk,我们可以如何实现

代码语言:javascript
复制
function encapsulateFunc(data) {

  return (dispatch) => {

    dispatch({

      type: 'BEFORE_ASYNC'

    })



    setTimeout(() => {

      dispatch({

        type: 'DOING_ASYNC',

        data

      })

    }, 0) 

  }

}

store.dispatch(encapsulateFunc({data: '4'}))

ecncapsulateFunc是一个action creator,不需要关心同步还是异步,返回的是对象还是函数,只需要关注传入的参数; 观察ecncapsulateFunc,我们会发现它返回了一个函数,参数传入dispatch,我们称ecncapsulateFunc为thunk函数,关于thunk不了解的可以戳链接http://www.ruanyifeng.com/blog/2015/05/thunk.html;

对比上述,使用redux-thunk可以帮助我们代码更优雅,封装设计更合理,当然redux-thunk是在我们需要的时候才引入,如果我们的实际项目明明可以简单解决,就不需要引入redux-thunk了。

middleware与store enhancer

redux-thunk是一个redux middleware,redux引入middleware方式如下:

代码语言:javascript
复制
import { createStore, applyMiddleware } from 'redux';

import thunkMiddleware from 'redux-thunk';

import reducer from './reducer';

const middleware = applyMiddleware(thunkMiddleware);

const store = createStore(

  reducer,

  window.initialState,

  middleware

)

将applyMiddlewarer方法执行的返回结果传入createStore第三个参数,那么applyMiddleware方法执行后返回了什么呢,查看redux官方文档,看到createStore的使用如下:

createStore(reducer, [preloadedState], [enhancer])

第三个参数enhancer可选,也就是说applyMiddleware方法返回了一个enhancer,这里的enhancer就是store enhancer, 所谓的enhancer就是增强原有的功能,正如middleware, redux-thunk通过包裹改造dispatch, 使得dispatch方法可以接受函数类型的参数,增强了dispatch的功能;而store,我们知道store有四个属性方法dispatch、getState、subscribe、replaceReducer,通过改造增强这些方法 ,也就可以enhance store, 一个store enhancer大概长这样:

代码语言:javascript
复制
function storeEnhancerCreator() {
  return createStore => (reducer, initialState, enchancer) => {
    var store = createStore(reducer, initialState);
    // do somethiing to enhance store here
         return store;
  }
}

基本上拓展功能使用middleware, 但如果有些场景需要改造store,可以试试通过创建一个store enhancer。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018-11-05 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档