Redux中间件原理
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Redux中间件原理相关的知识,希望对你有一定的参考价值。
参考技术A Redux提供了非常强大的数据流管理功能,是一个可预测的状态容器,解决数据在 React 应用中的流动方式及过程Redux 的中间件提供的是位于 action 被发起之后,到达 reducer 之前的扩展点,这种机制可以让我们改变数据流,实现如异步 action ,action 过滤,日志输出,异常报告等功能。
原redux的数据流:view -> action -> reducer -> store
加上中间件后变成了: view -> action -> middleware -> reducer -> store
createStore函数接收参数为(reducer, [initState], enhancer)
enhancer是一个组合 StoreCreator 的高阶函数, 返回的是一个新的强化过的 StoreCreator,再执行StoreCreator就能得到一个加强版的 store。
例子中enhancer即为applyMiddleware,从下面的源码可知,applyMiddleware 改写了 store 的 dispatch 方法,新的 dispatch 即是被所传入的中间件包装过的。
applyMiddleware 的源码:
参数 dispatch 和 getState,分别代表着 Redux Store 上的两个同名函。然后中间件doNothingMidddleware 返回的函数接受一个 next 类型的参数,这个 next 是一个函数,如果调用了它,就代表着这个中间件完成了自己的职能,并将对 action 控制权交予下一个中间件。最后以 action 为参数的函数对传入的 action 对象进行处理,在这个地方可以进行操作,比如:
在具有上面这些功能后,一个中间件就足够获取 Store 上的所有信息,也具有足够能力可用之数据的流转。
最出名的中间件 redux-thunk,可以处理异步操作 :
redux-thunk 中间件的功能很简单。首先检查参数 action 的类型,如果是函数的话,就执行这个 action 函数,并把 dispatch, getState, extraArgument 作为参数传递进去,否则就调用 next 让下一个中间件继续处理 action 。
另外还有一些中间件如redux-logger(打印日志)、redux-promise(处理异步操作,但是返回Promise对象)、redux-saga等
redux-observable笔记
欢迎指导与讨论:)
前言
本文不涉及深入的知识,只是在概念层面和一个简单的例子解释redux-observable的工作原理。
redux-observable,是redux的一个中间件库。它能够自动响应我们所dispatch的actions并执行对应的函数,让我们把复杂的异步函数分离到一些Epic的函数里面。因此不再需要react-thunk来让redux支持所谓的异步action了,同时让代码耦合度降得更低。redux-observable让redux的action更加纯净,都是干净的对象字面量 —— redux-observable适合大型复杂的状态管理,而且让代码分离度和可维护度更高。但可能需要先掌握RxJS的基本概念和api用法。
几个概念
可观察流与自动响应、redux的dispatch、Epics函数、redux-observable的内部原理。
可观察流与自动响应
可观察流相当于一个发射器,它能够随时间地流逝不断 发送/产生 各种各样的值,当我们监听这个发射器时,就会收到发射过来的值并可以执行我们想要的操作。而启动这个监听,需要触发 .subscribe( ) 。每当有一个新值发送时,subscribe里的代码就会自动执行 —— 自动响应。
// 一个简单的例子
发射器.subscribe( function( 收到的值 ){
// 根据值可以进行一些函数操作
})
redux的dispatch( action )
redux的dispatch(action)函数能够根据action类型的不同,让应用的状态store响应它的变化。每当dispatch一个action时,应用状态可能就会更变。
// 下面代码触发时,应用状态会被刷新
dispatch({ type: ‘man‘ })
Epics函数
redux-observable里的Epics函数主要作用是:1. 传进一个action,然后return一个新的、不一样的action。2. 这个Epics函数是一个发射器,因此我们能够subscribe它,从而可以监听并收到新的action。3. 每当我们调用redux的dispatch的时候,所有的Epics函数都会执行。
function (action$: Observable<Action>, store: Store): Observable<Action>;
redux-observable的内部原理
( 1 ) 每当我们使用redux的dispatch的时候,每个Epics函数都会收到我们所dispatch的action,然后Epics函数返回一个新的action。
(2)监听Epics函数,将它返回的新的action,用来dispatch,从而更新应用状态
// 用代码表示就是
epic(actions$).subscribe( function( newAction ){
dispatch( newAction ) // dispatch新的action
})
一个简单的例子
// 定义两个action creator
// 1. 拉取某用户数据
const fetchUser = username => ({ type: ‘拉取某用户数据‘, target: username });
// 2. 拉取完成
const fetchUserDone = data => ({ type: ‘拉取完成‘, data});
// 定义一个Epics函数
const fetchEpics = action$ =>
action$.ofType(‘拉取某用户数据‘) // 如果true则进行下一步否则退出
.mergeMap( action =>
// 提取action.target并进行ajax请求
ajax.getJson(`/api/users/${action.target}`)
.map(function( data ){
fetchUserDone ( data )// 调用拉取完成函数,返回{ type: ‘拉取完成‘, data }
})
);
从上面的这个例子我们看到:
(1)不再有异步action,即类型为函数的这种action,redux的action都是纯净的对象字面量了。
(2)拉取数据的函数写到了Epics函数里面
(3)Epics函数会对action的类型进行判断,满足不了不会继续执行
(4)注:上面的mergeMap、ajax、map这几个都是RxJS的api。
总结
redux-observable的优点大概有这几个,欢迎补充。(1)会自动响应redux的dispatch,每当触发时都会执行我们定义的Epics函数。(2)把拉取数据等等的业务逻辑代码可以分离到Epics函数里面,降低代码耦合度,提升维护度(3)action都是纯净的对象字面量,不再需要引入redux-thunk。
以上是关于Redux中间件原理的主要内容,如果未能解决你的问题,请参考以下文章
Redux和React-Redux的实现:中间件的原理和applyMiddlewareThunk的实现
Redux之中间件的原理和applyMiddlewareThunk的实现