Redux中间件组合方法
中间件
https://redux.js.org/glossary#middleware
中间件在发送端 action端点 和 处理方reducer的端点之间。
主要负责将async action转换为action, 或者记录action日志。
A middleware is a higher-order function that composes a dispatch function to return a new dispatch function. It often turns async actions into actions.
Middleware is composable using function composition. It is useful for logging actions, performing side effects like routing, or turning an asynchronous API call into a series of synchronous actions.
import { createStore, applyMiddleware } from 'redux'
import todos from './reducers'
function logger({ getState }) {
return next => action => {
console.log('will dispatch', action)
// Call the next dispatch method in the middleware chain.
const returnValue = next(action)
console.log('state after dispatch', getState())
// This will likely be the action itself, unless
// a middleware further in chain changed it.
return returnValue
}
}
const store = createStore(todos, ['Use Redux'], applyMiddleware(logger))
store.dispatch({
type: 'ADD_TODO',
text: 'Understand the middleware'
})
// (These lines will be logged by the middleware:)
// will dispatch: { type: 'ADD_TODO', text: 'Understand the middleware' }
// state after dispatch: [ 'Use Redux', 'Understand the middleware' ]
http://www.ruanyifeng.com/blog/2016/09/redux_tutorial_part_two_async_operations.html
let next = store.dispatch;
store.dispatch = function dispatchAndLog(action) {
console.log('dispatching', action);
next(action);
console.log('next state', store.getState());
}
上面代码中,对
store.dispatch进行了重定义,在发送 Action 前后添加了打印功能。这就是中间件的雏形。中间件就是一个函数,对
store.dispatch方法进行了改造,在发出 Action 和执行 Reducer 这两步之间,添加了其他功能。
应用多个中间件
https://redux.js.org/api/applymiddleware
applyMiddleware(...middleware)Middleware is the suggested way to extend Redux with custom functionality. Middleware lets you wrap the store's
dispatchmethod for fun and profit. The key feature of middleware is that it is composable. Multiple middleware can be combined together, where each middleware requires no knowledge of what comes before or after it in the chain.Arguments
...middleware(arguments): Functions that conform to the Redux middleware API. Each middleware receivesStore'sdispatchandgetStatefunctions as named arguments, and returns a function. That function will be given thenextmiddleware's dispatch method, and is expected to return a function ofactioncallingnext(action)with a potentially different argument, or at a different time, or maybe not calling it at all. The last middleware in the chain will receive the real store'sdispatchmethod as thenextparameter, thus ending the chain. So, the middleware signature is({ getState, dispatch }) => next => action.Returns
(Function) A store enhancer that applies the given middleware. The store enhancer signature is
createStore => createStorebut the easiest way to apply it is to pass it tocreateStore()as the lastenhancerargument.
应用中间件函数实现, 注意其中 对于middlewares数组, 使用compose函数进行组合, 其串联方式是从 右 到 左, 即最右边的被包裹为最里层,最先执行, 最左边的被包裹到最外面, 最后执行。
https://www.cnblogs.com/liaozhenting/p/10166671.html
export default function applyMiddleware(...middlewares) {
return createStore => (...args) => {
const store = createStore(...args)
let dispatch = () => {
throw new Error(
`Dispatching while constructing your middleware is not allowed. ` +
`Other middleware would not be applied to this dispatch.`
)
}
const middlewareAPI = {
getState: store.getState,
dispatch: (...args) => dispatch(...args)
}
const chain = middlewares.map(middleware => middleware(middlewareAPI))
dispatch = compose(...chain)(store.dispatch)
return {
...store,
dispatch
}
}
}
如下图很形象:
https://zhuanlan.zhihu.com/p/20597452

compose
https://www.cnblogs.com/liaozhenting/p/10166671.html
/**
* Composes single-argument functions from right to left. The rightmost
* function can take multiple arguments as it provides the signature for
* the resulting composite function.
*
* @param {...Function} funcs The functions to compose.
* @returns {Function} A function obtained by composing the argument functions
* from right to left. For example, compose(f, g, h) is identical to doing
* (...args) => f(g(h(...args))).
*/ export default function compose(...funcs) {
if (funcs.length === 0) {
return arg => arg
} if (funcs.length === 1) {
return funcs[0]
} return funcs.reduce((a, b) => (...args) => a(b(...args)))
}
与pipe正好相反:
const pipe = (...fns) => {
return (args) => {
return fns.reduce((args, fn) => {
return fn(args)
}, args)
}
}
const toUpper = (value) => {
return value.toUpperCase();
}
const addFont = (value) => {
return 'hello plus!' + value;
}
console.log(pipe(addFont,toUpper)('test'));
// HELLO PLUS!TEST
跟pip函数对比
console.log(pipe(addFont,toUpper)('test'));
// HELLO PLUS!TEST
console.log(compose(addFont,toUpper)('test'));
// hello plus!TEST
underscore compose
http://www.bootcss.com/p/underscore/#compose
compose
_.compose(*functions)
返回函数集 functions 组合后的复合函数,
也就是一个函数执行完之后把返回的结果再作为参数赋给下一个函数来执行.
以此类推.
在数学里, 把函数 f(), g(), 和 h() 组合起来可以得到复合函数 f(g(h()))。var greet = function(name){ return "hi: " + name; };
var exclaim = function(statement){ return statement.toUpperCase() + "!"; };
var welcome = _.compose(greet, exclaim);
welcome('moe');
=> 'hi: MOE!'
Redux中间件组合方法的更多相关文章
- react+redux教程(七)自定义redux中间件
今天,我们要讲解的是自定义redux中间件这个知识点.本节内容非常抽象,特别是中间件的定义原理,那多层的函数嵌套和串联,需要极强逻辑思维能力才能完全消化吸收.不过我会多罗嗦几句,所以不用担心. 例子 ...
- 【React全家桶入门之十三】Redux中间件与异步action
在上一篇中我们了解到,更新Redux中状态的流程是这种:action -> reducer -> new state. 文中也讲到.action是一个普通的javascript对象.red ...
- redux中间件和redux-thunk实现原理
redux-thunk这个中间件可以使我们把这样的异步请求或者说复杂的逻辑可以放到action里面去处理,redux-thunk使redux的一个中间件,为什么叫做中间件 我们说中间件,那么肯定是谁和 ...
- Redux 中间件与函数式编程
为什么需要中间件 接触过 Express 的同学对"中间件"这个名词应该并不陌生.在 Express 中,中间件就是一些用于定制对特定请求的处理过程的函数.作为中间件的函数是相互独 ...
- 3.3 理解 Redux 中间件(转)
这一小节会讲解 redux 中间件的原理,为下一节讲解 redux 异步 action 做铺垫,主要内容为: Redux 中间件是什么 使用 Redux 中间件 logger 中间件结构分析 appl ...
- 理解 Redux 中间件机制
Redux 的 action 是一个 JS 对象,它表明了如何对 store 进行修改.但是 Redux 的中间件机制使action creator 不光可以返回 action 对象,也可以返回 ac ...
- Redux:中间件
redux中间件概念 比较容易理解. 在使用redux时,改变store state的一个固定套路是调用store.dispatch(action)方法,将action送到reducer中. 所谓中间 ...
- react第十八单元(redux中间件redux-thunk,redux工程目录的样板代码,规范目录结构)
第十八单元(redux中间件redux-thunk,redux工程目录的样板代码,规范目录结构) #课程目标 中间件:中间件增强redux的可扩展性,实现功能复用的目的. redux-thunk异步逻 ...
- redux 中间件 redux-saga 使用教程
redux 中间件 redux-saga 使用教程 redux middleware refs https://redux-saga.js.org/docs/ExternalResources.htm ...
随机推荐
- Delphi中常用字符串处理函数
.copy(str,pos,num) 从str字符串的pos处开始,截取num个字符的串返回. 假设str为,)=,)='def' .concat(str1,str2{,strn}) 把各自变量连接起 ...
- Hibernate执行SQL语句实现查询修改功能!
今天玩Hibernate时突然就想写写SQL语句查询... DAO : //查询 public List<?> createSqlQueryList(final String queryS ...
- Codeception 实战
Codeception 测试 Php 代码 一.一句话概述 使用 cc 进行单元测试,保证现有代码质量,为以后维护与重构提供支撑. 二.目标 安装配置 cc 编写测试代码,简化开发与最大化稳定性和可维 ...
- 功能测试话题分享-0323 Bug
- 你注意到 .Net Framework 和 .Net Core 中使用 Session 的区别了吗?
起因 在测试一个例子时发现的问题,这个示例实现的功能是刷新页面也能保持表格锁定列的状态,先看下页面的完成效果: 测试中发现,几乎相同的代码: 在 FineUIMvc(Net Framework)下没有 ...
- 如何使用ASP.NET Core、EF Core、ABP(ASP.NET Boilerplate)创建分层的Web应用程序(第一部分)
本文是为了学习ABP的使用,是翻译ABP官方文档的一篇实战教程,我暂时是优先翻译自己感兴趣或者比较想学习的部分,后续有时间希望能将ABP系列翻译出来,除了自己能学习外,有可能的话希望帮助一些英文阅读能 ...
- java集合-HashSet源码解析
HashSet 无序集合类 实现了Set接口 内部通过HashMap实现 // HashSet public class HashSet<E> extends AbstractSet< ...
- telnet-server、telnet
1.查询yum仓库中的安装包 [root@localhost /]# yum list |grep telnettelnet.x86_64 1 ...
- 【NLP】BLEU值满分是100分吗?
为了解决这个问题,首先需要知道BLEU值是如何计算出来的. BLEU全称是Bilingual Evaulation Understudy.其意思是双语评估替补.所谓Understudy(替补),意思是 ...
- 内存溢出OOM
如何避免OOM 异常? 想要避免OOM 异常首先我们要知道什么情况下会导致OOM 异常. 1.图片过大导致OOM Android 中用bitmap 时很容易内存溢出,比如报如下错误:Java.lang ...