Redux 的黑魔法
相信很多人接触 Redux 时都会被它奇怪的 API 搞得云里雾里。这里不再冗述 Flux 架构的思想,实现 Flux 的工具有很多,它们只是在实现这种编程模式,并不会有太复杂的逻辑。事实也是这样,Redux 的 API 非常少,但并不一定容易理解。 createStore
const store = createStore((state = {counter: 0},action) => { switch(action.type) { case 'add': return Object.assign({},state,{counter: state.counter + 1}); case 'minus': return Object.assign({},{counter: state.counter - 1}); default: return state; } }); combineReducers辅助函数,分解 reducer 之用。如: // 分解前 const reducer = (state = {counter: 0,status: 'idle'},action) => { }; createStore(reducer); // 分解后 const counter = (state = 0,action) => {}; const status = (state = 'idle',action) => {}; createStore(combineReducers({counter,status})); 可见 applyMiddleware一种 store enhancer,使用 compose 来强化 createStore 的能力。这一个理解起来非常绕的函数。它允许对 createStore 进行多层包装,并修改了返回的 store 对象,可以在 dispatch 操作前后执行其它逻辑,有点类似 AOP 的感觉。事实上只要包装 dispatch 方法就能实现这些功能,也印证了 Redux文档 的这句: Middleware only wraps the store’s dispatch function. Technically,anything a middleware can do,you can do manually by wrapping every dispatch call,but it’s easier to manage this in a single place and define action transformations on the scale of the whole project. bindActionCreators辅助函数: function addTodoActionCreator(text){ return { type: "add",text: text }; } // 调用 bindActionCreators(addTodoActionCreator,dispatch) 后 function addTodoAction(text){ dispatch({ type: "add",text: text }); } // 这样可以直接调用addTodoAction来派发 Action。 我们也可以实现自己的 function bindActionCreators (actionCreators,dispatch) { if('function' === typeof actionCreators) { return function () { dispatch(actionCreators.apply(arguments)); }; } else { let ret = {}; for (let e in actionCreators) { if('function' === typeof actionCreators[e]) { ret[e] = bindActionCreators(actionCreators[e],dispatch); } } return ret; } } compose辅助函数,用以解构深度嵌套函数,体现了柯里化的编程模式,如: function $1 (func) { return function () { return func.apply(null,arguments)+ '1'; }; } function $2 (func) { return function () { return func.apply(null,arguments) + '2'; }; } function $3 (num) { return num; } $1($2($3))(3);// 321 (compose($1,$2,$3))(3)// 321 你也可以实现自己的 function compose () { const args = Array.prototype.slice.call(arguments).reverse(); let tmp = args[0]; if (!tmp) { return function (a) { return a; } } for( let i = 1; i < args.length; ++i){ tmp = (args[i])(tmp); } return tmp; } 除了 除了不十分常用并且仍可自实现的 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |