redux-applyMiddleware实现理解+自定义中间件
2017-02-19 15:23
441 查看
前言:
http://www.cnblogs.com/miaowwwww/p/6265323.html
终于好好理解了middleware。。。。
1.redux middleware提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。
redux通过store.dispatch(atcion),发起一个action给store,store接收后把当前state与action一起传给reducer,所以middleware做文章的地方就是dispatch,在原生的dispatch执行之前,先进行一些列的操作。
实现middleware的方法:下面以logger中间件为例
1.手动记录(不可能会使用这种的吧)
2.封装dispatch,
要发起action的时候,不用 dispatch 而是用 disptchAddLog()。(把这个方法放在store里面、好像还不错的样子)
3.猴子补丁,
通过重写store.dispatch(), (重写之后,所使用的dispatch(), 已经不是原生的dispatch了,使用多个中间件,就是不断改写前一次生成的dispatch),
(注意:原生的dispatch,已经不可能找到,也就是不能单独使用原始dispatch了)
4.隐藏猴子补丁,
乍一看好像和猴子补丁没什么却别,但其实它把赋值的给store.dispatch的逻辑放到了中间件函数的外面,需要外面提过一个applyMiddleware辅助函数来完成插值,除此之外,真的没什么区别。(原理还是猴子补丁)
多个中间件 的实现方式:
5.移除猴子补丁,
相对隐藏猴子不同,把middleware函数里面 let next = store.dispatch ,放到函数外面 dispatch
= middleware(store)(dispatch)
看一下多个中间件实现方式你就知道了,
是否发现:在 return 的 assign 之前, store.dispatch 都是原生的,并没有被改变。所以中间件里面是否可以使用store.dispatch调用原生的,(如果有需要的话),然而笔者试着调用了一下,并不行,会不断的触发,就是已经是该改变之后的了。
logger中间件换成es6的箭头函数更好看
6.redux中是现实方法
这与 Redux 中
它只暴露一个 store API 的子集给 middleware:
它用了一个非常巧妙的方式来保证你的 middleware 调用的是
action 会在包括当前 middleware 在内的整个 middleware 链中被正确的传递。这对异步的 middleware 非常有用。
为了保证你只能应用 middleware 一次,它作用在
而是
总结:
redux提供了applyMiddleware(), 如果我们自定义中间件,也就变的很简单了
applyMiddleware会帮我们执行前面两层函数。myMiddleware(store)(dispatch)
redux-thunk的实现也是很牛掰
http://www.cnblogs.com/miaowwwww/p/6265323.html
终于好好理解了middleware。。。。
1.redux middleware提供的是位于 action 被发起之后,到达 reducer 之前的扩展点。
redux通过store.dispatch(atcion),发起一个action给store,store接收后把当前state与action一起传给reducer,所以middleware做文章的地方就是dispatch,在原生的dispatch执行之前,先进行一些列的操作。
实现middleware的方法:下面以logger中间件为例
1.手动记录(不可能会使用这种的吧)
let action = addTodo('Use Redux') console.log('dispatching', action) store.dispatch(action) console.log('next state', store.getState())
2.封装dispatch,
要发起action的时候,不用 dispatch 而是用 disptchAddLog()。(把这个方法放在store里面、好像还不错的样子)
function dispatchAndLog(store, action) { console.log('dispatching', action) store.dispatch(action) console.log('next state', store.getState()) }
3.猴子补丁,
通过重写store.dispatch(), (重写之后,所使用的dispatch(), 已经不是原生的dispatch了,使用多个中间件,就是不断改写前一次生成的dispatch),
(注意:原生的dispatch,已经不可能找到,也就是不能单独使用原始dispatch了)
function(store) { let next = store.dispatch store.dispatch = function dispatchAndLog(action) { console.log('dispatching', action) let result = next(action) console.log('next state', store.getState()) return result } }
4.隐藏猴子补丁,
乍一看好像和猴子补丁没什么却别,但其实它把赋值的给store.dispatch的逻辑放到了中间件函数的外面,需要外面提过一个applyMiddleware辅助函数来完成插值,除此之外,真的没什么区别。(原理还是猴子补丁)
function logger(store) { let next = store.dispatch // 我们之前的做法: // store.dispatch = function dispatchAndLog(action) { return function dispatchAndLog(action) { console.log('dispatching', action) let result = next(action) console.log('next state', store.getState()) return result } }
多个中间件 的实现方式:
function applyMiddlewareByMonkeypatching(store, middlewares) { middlewares = middlewares.slice() middlewares.reverse() // 在每一个 middleware 中变换 dispatch 方法。 middlewares.forEach(middleware => store.dispatch = middleware(store) ) }
5.移除猴子补丁,
相对隐藏猴子不同,把middleware函数里面 let next = store.dispatch ,放到函数外面 dispatch
= middleware(store)(dispatch)
function logger(store) { return function wrapDispatchToAddLogging(next) { return function dispatchAndLog(action) { console.log('dispatching', action) let result = next(action) console.log('next state', store.getState()) return result } } }
看一下多个中间件实现方式你就知道了,
是否发现:在 return 的 assign 之前, store.dispatch 都是原生的,并没有被改变。所以中间件里面是否可以使用store.dispatch调用原生的,(如果有需要的话),然而笔者试着调用了一下,并不行,会不断的触发,就是已经是该改变之后的了。
// 警告:这只是一种“单纯”的实现方式! // 这 *并不是* Redux 的 API. function applyMiddleware(store, middlewares) { middlewares = middlewares.slice() middlewares.reverse() let dispatch = store.dispatch middlewares.forEach(middleware => dispatch = middleware(store)(dispatch) ) return Object.assign({}, store, { dispatch }) }
logger中间件换成es6的箭头函数更好看
const logger = store => next => action => { console.log('dispatching', action) let result = next(action) console.log('next state', store.getState()) return result }
6.redux中是现实方法
这与 Redux 中
applyMiddleware()的实现已经很接近了,但是有三个重要的不同之处:
它只暴露一个 store API 的子集给 middleware:
dispatch(action)和
getState()。
它用了一个非常巧妙的方式来保证你的 middleware 调用的是
store.dispatch(action)而不是
next(action),从而使这个
action 会在包括当前 middleware 在内的整个 middleware 链中被正确的传递。这对异步的 middleware 非常有用。
为了保证你只能应用 middleware 一次,它作用在
createStore()上而不是
store本身。因此它的签名不是
(store, middlewares) => store,
而是
(...middlewares) => (createStore) => createStore。
总结:
redux提供了applyMiddleware(), 如果我们自定义中间件,也就变的很简单了
function myMiddleware = (store) => (next) => (action) => { console.log('进入了我自己定义的中间件'); let result = next(action); // 执行下一步 // let result = store.dispatch(action); //不调用next,直接使用store.dispatch调用原生。然后是不行的,会陷入dispatch死循环。 return result; }
applyMiddleware会帮我们执行前面两层函数。myMiddleware(store)(dispatch)
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;
相关文章推荐
- 通过c# 实现自定义属性改变触发自定义事件 ,理解自定义事件及其触发过程
- 基础篇-View事件传递与绘制机制,自定义View实现理解
- [原创]使用自定义类库实现中间件的功能
- .net core系列之《对AOP思想的理解及使用AspectCore实现自定义日志拦截》
- JAVA 中Comparator接口实现自定义排序的理解
- 深入理解自定义Annotation,实现ButterKnif小原理
- redux深入理解之中间件(middleware)
- 自定义注解实现--简单理解版
- react+redux教程(七)自定义redux中间件
- 【Android个人理解(二)】从实现方法深入了解自定义适配器的工作过程
- Android 自定义View实现圆形进度条 深入理解onDraw和onMeasure及自定义属性
- redux深入理解之中间件(middleware)
- File类ListFIles()中的过滤器学习和理解包含自定义过滤器实现FileFilter
- Spring Boot 自动配置理解 以及实现自定义Starter
- redux深入理解之中间件(middleware)
- StateBag.cs实现代码 对理解实现自定义状态管理很有帮助。
- 从函数的柯里化,看Redux中间件的实现
- View事件传递与绘制机制,自定义View实现理解
- redux深入理解之中间件(middleware)
- 使文件下载的自定义连接支持 FlashGet 的断点续传多线程链接下载! C#/ASP.Net 实现