我们改写了,dispatch方法实现了在更改状态时打印前后的状态,但是这种方案并不好。所以我们可以采用中间的方式。
let store = createStore(reducer);
let dispatch = store.dispatch;
store.dispatch = function (action) {
console.log(store.getState().number);
dispatch(action);
console.log(store.getState().number)
};
export default store;
let logger = store => dispatch => action=>{
console.log(store.getState().number);
dispatch(action);
console.log(store.getState().number)
};
let applyMiddleWare = middleware => createStore => reducer =>{
let store = createStore(reducer);
let middle = middleware(store);
let dispatch = middle(store.dispatch);
return { //将中间返回的dispatch方法覆盖掉原有store中的dispatch
...store,
dispatch
}
};
export default applyMiddleWare(logger)(createStore)(reducer);
实现派发异步动作,actionCreator可以返回函数,可以把dispatch的权限交给此函数
// action
export default {
add(amount){
return function (dispatch,getState) {
dispatch({type:Types.ADD,amount});
dispatch({type:Types.ADD,amount});
console.log(getState().number);
}
},
minus(amount){
return {type:Types.MINUS,amount}
}
}
// store/index.js
let reduxThunk = store => dispatch => action=>{
if(typeof action === 'function'){ //如果是函数将派发的权限传递给函数
return action(dispatch,store.getState);
}
dispatch(action);
};
// action
minus(amount){
return {
type:Types.MINUS,
payload:new Promise(function (resolve,reject) {
reject({amount:2});
})
}
}
//store/index.js
let reduxPromise = store => dispatch => action=>{
if(action.then){
return action.then(dispatch); //只支持成功
}else if(action.payload&&action.payload.then){
// 如果payload是一个promise 会对成功和失败都进行捕获并且将成功或失败的数据放到payload中进行派发
return action.payload.then(function (data) {
dispatch({...action,payload:data});
},function (data) {
dispatch({...action,payload:data});
})
}
dispatch(action);
};
function toResult(who,decorator) {
return who+decorator;
}
function len(str) {
return str.length
}
// 我们的目的是将第一个函数的返回结果传递给第二个函数
console.log(len(toResult('Mrs jiang', '很帅')));
这个compose也是redux中的一个方法
let compose = (...fns)=>(...args)=> {
let last = fns.pop();
return fns.reduceRight(function (prev,next) {
return next(prev);
},last(...args))
};
console.log(compose(len, toResult)('Mrs jiang', '很帅'));
let applyMiddleWare = (...middlewares) => createStore => reducer =>{
let store = createStore(reducer);
let middles = middlewares.map(middleware=>middleware(store))
let dispatch = compose(...middles)(store.dispatch);
return {
...store,
dispatch
}
};
最终实现效果
export default createStore(reducer,applyMiddleware(reduxThunk,reduxPromise));
最终版redux库
let createStore = (reducer, fn) => {
let state;
let listeners = [];
let getState = () => state;
let dispatch = (action) => {
state = reducer(state, action);
listeners.forEach(item => item());
};
dispatch({});
let subscribe = (l) => {
listeners.push(l);
return () => {
listeners = listeners.filter(item => item !== l);
}
};
if (typeof fn === 'function') {
return fn(createStore, reducer);
}
return {
createStore,
dispatch,
getState,
subscribe
}
};
let combineReducers = (reducers) => (newState = {}, action) => {
for (let key in reducers) {
newState[key] = reducers[key](newState[key], action)
}
return newState;
};
let bindActionCreators = (actions, dispatch) => {
let obj = {};
for (let key in actions) {
obj[key] = (...args) => dispatch(actions[key](...args))
}
return obj
};
let applyMiddleware = (...middlewares) => (createStore, reducer) => {
let store = createStore(reducer);
let middles = middlewares.map(middleware => middleware(store));
let dispatch = compose(...middles)(store.dispatch);
return {
...store,
dispatch
}
};
let compose = (...fns) => {
return (...args) => {
let fn = fns.pop();
return fns.reduceRight((prev, next) => {
return next(prev);
}, fn(...args));
}
};
export {createStore, combineReducers, bindActionCreators, applyMiddleware, compose}