redux 插件的实现
1、插件使用
const store = createStore(countReducer, applyMiddleware(thunk, logger))
// applyMiddleware(thunk, logger) 就是引入插件
// store内部
export default function createStore(reducer, enhancer) {
if (enhancer) { // 插件
return enhancer(createStore)(reducer) // 这里引入插件
}
// ....
return {
getState,
dispatch,
subscribe
}
}
2、插件实现
1、利用闭包,传入操作权限返回一个函数
2、这个函数
// 支持日志输出
export function logger({ getState }) {
return (next) => {
console.log('logger生成')
return (action) => {
console.log(action.type + ':logger执行')
//sy-log
const prevState = getState()
console.log('prev state', prevState) //sy-log
const returnValue = next(action)
const nextState = getState()
console.log('next state', nextState) //sy-log
return returnValue
}
}
}
// 支持传入函数
export function thunk({ dispatch, getState }) {
return (next) => {
console.log('thunk生成')
return (action) => {
console.log('thunk执行')
if (typeof action === 'function') {
return action(dispatch, getState)
}
const x = next(action)
console.log('thunk后置')
return x
}
}
}
function isPromise(promise) {
return typeof promise === 'object' && /Promise/g.test(promise.toString())
}
// 支持promise执行 传入的promise返回必须是 包含type了,且该promise不会继续走日志部分
export function promise({ dispatch }) {
return (next) => (action) => {
return isPromise(action) ? action.then(dispatch) : next(action)
}
}
// 这里实际实现,方法 (ops操作曲线) => 函数1
// 函数1 为 传入一个dispatch方法返回一个加工后dispatch函数
applyMiddleware 加入插件的方法
export function applyMiddleware(...middlewares) {
return (createStore) => (reducer) => {
const store = createStore(reducer) // 创建存储器
let dispatch = store.dispatch // 获取派发‘
// 提供操作权限
const midApi = {
getState: store.getState,
dispatch: (action, ...args) => dispatch(action, ...args)
}
// 这里每步按照reduce的策略都是传入一个dispatch函数
// 返回一个dispatch函数
// (next) => (action)=> {
// 作前置处理
// const x =next(action)
// 作后置处理
// return x
// }
const middlewareChain = middlewares.map((middleware) => middleware(midApi))
dispatch = compose(...middlewareChain)(store.dispatch)
return {
...store // 加强版的dispatch
}
}
}
3、compose 方法
const comreducer = (a, b) => (...args) => a(b(...args))
function compose(...args) {
if (args.length === 0) {
return null
}
return args.reduce(comreducer)
}
思考题
applyMiddleware(thunk, logger) 这样导致执行的顺序是怎样