博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
从零开始写一个 redux(第四讲)
阅读量:6772 次
发布时间:2019-06-26

本文共 3039 字,大约阅读时间需要 10 分钟。

接着上一讲的中间件机制继续讲。 上一讲中我们实现了redux-thunk中间件,使得增强后的dispatch不仅能够接收对象类型的action,还能够接收函数类型的action。 在此我们是否能够在构造一个中间件,使得增强后的dispatch还能处理action组成的数组,如下:

export function buyHouse() {    return {
type: BUY_House}}export function buyHouseAsync() { return dispatch => { setTimeout(() => { dispatch(buyHouse()) }, 2000) }}export function buyTwice() { return [buyHouse(), buyHouseAsync()]}复制代码

构造中间件redux-arrThunk

为此我们决定再构造一个中间件,命名redux-arrThunk,使增强后的dispatch还能处理action组成的数组。代码如下:

const arrThunk = ({dispatch, getState}) => next => action => {    // next为原生的dispatch    // 如果是数组,依次执行数组中每一个action,参数是dispatch和getState    if (Array.isArray(action)) {        return action.forEach(v=>dispatch(v))    }    // 如果不满足条件,则直接调用下一个中间件(使用next)    // 如果满足条件,则需要重新dispatch(调用dispatch)    // 默认直接用原生dispatch发出action    return next(action)}复制代码

中间件叠加使用

因为原理类似第三讲中的redux-thunk,上面的代码并不难,但问题是,我们如何将这两个中间件叠加起来使用,为此我们需要修改之前的applyMiddleware函数,使其能够接收多个中间件,并且是的这些中间件能够叠加使用。代码如下:

// applyMiddlewareexport function applyMiddleware(...middlewares) {    return createStore => (...args) => {        // 第一步 获得原生store以及原生dispatch        const store = createStore(...args)        let dispatch = store.dispatch                const midApi = {            getState: store.getState,            dispatch: (...args) => dispatch(...args)        }        // 第二步 将原生dipatch传入中间件进行扩展增强,生成新的dispatch        const middlewaresChain = middlewares.map(middleware => middleware(midApi))        dispatch = compose(...middlewaresChain)(dispatch)        // dispatch = middleware(midApi)(dispatch)        return {            ...store, // 原生store            dispatch, // 增强扩展后的dispatch        }    }}// compose//compose(fn1, fn2, fn3) return为 fn1(fn2(fn3))export function compose(...funcs) {    if (funcs.length === 0) {        return arg => arg    }    if (funcs.length === 1) {        return funcs[0]    }    return funcs.reduce((ret, item) => (...args) => ret(item(...args)))}复制代码

对比上一讲中的applyMiddleware,这一次主要是在处理中间件时,对中间件进行了遍历,并且通过compose方法使得多个中间件可以叠加使用,即将fn1, fn2, fn3 转换为 fn1(fn2(fn3))

// 之前dispatch = middleware(midApi)(dispatch)// 之后const middlewaresChain = middlewares.map(middleware => middleware(midApi))dispatch = compose(...middlewaresChain)(dispatch)复制代码

因此可以像如下代码一样进行叠加使用多个中间件

import React from 'react'import ReactDOM from 'react-dom'import { createStore, applyMiddleware } from './mini-redux'import { Provider } from './mini-react-redux'import { counter } from './index.redux'import thunk from './mini-redux-thunk'import arrThunk from './mini-redux-arrThunk'import App from './App'const store = createStore(counter, applyMiddleware(thunk, arrThunk))ReactDOM.render(    (        
), document.getElementById('root'))复制代码

其中const store = createStore(counter, applyMiddleware(thunk, arrThunk)),意味着增强后的dispatch具有如下功能

dispatch(action) = thunk(arrThunk(midApi)(store.dispatch)(action))复制代码

至此,我们的 mini 版 redux 就开发完成咯,有任何问题或意见欢迎联系我。

另外最近正在写一个编译 Vue 代码到 React 代码的转换器,欢迎大家查阅。

转载于:https://juejin.im/post/5d05b4da5188250a8b1fd29d

你可能感兴趣的文章
SQL将原始数据进行MD5加密转存
查看>>
rabbitmq启动异常之error,{not_a_dets_file recovery.dets
查看>>
关于webpack.optimize.CommonsChunkPlugin的使用二
查看>>
Python Locust对指定网站“一键压测”
查看>>
【hrbust2294】修建传送门
查看>>
mysql 5.7.15单机主从快速搭建并配置复制表到不同库
查看>>
Java 命名空间的由来和引入
查看>>
2016最后一贴,终于调通一个测试示例,并发现一个BUG???
查看>>
2016 年开发者头条十大文章系列
查看>>
JavaScript学习笔记(三)——this、原型、javascript面向对象
查看>>
2017第一周六
查看>>
转: 测试云服务器的工具相关
查看>>
用myeclipse 创建maven项目时,生成的项目名中总是包含Maven Webapp
查看>>
分布式事务 & 两阶段提交 & 三阶段提交
查看>>
linux下编译upx 3.93
查看>>
MySQL 优化
查看>>
混合背包 hdu5410 CRB and His Birthday
查看>>
MCMC采样理论的一点知识
查看>>
bram和dram差别
查看>>
Java用freemarker导出word
查看>>