Redux
首先一张图看看Redux
基本内容:
react-redux
还是一张图看看如何在React
中使用Redux
:
中间件
这就不是一张图可以解释的了。
什么是中间件
允许开发者在派发一个action
到他最终被reducer
处理之前,对action
进行一些额外的处理。
主要是增强store.dispatch
的能力。
如何自定义中间件
重写dispatch方法
类似于VUE
中数组实现响应式的原理:
js
import { combineReducers,createStore } from 'redux';
import countReducer from "./reducers/count";
import userReducer from "./reducers/user";
const rootReducer = combineReducers({
count:countReducer,
user:userReducer
});
const store = createStore(rootReducer);
// 通过重写dispatch实现响应式
const originDispatch= store.dispatch; //缓存原始dispatch
store.dispatch = function(action){
// 执行中间操作
console.log('中间件获取action',action);
console.log('中间件获取state',store.getState());
originDispatch(action); //调用原始dispatch
};
export default store;
官方推荐方法
自定义 Redux 中间件通常涉及编写一个函数,该函数接收 store
对象的 dispatch
和 getState
方法,并返回一个函数,该函数再次接收 next
和 action
,允许你在 action 到达 reducer 之前或之后执行一些逻辑。
js
const loggerStateMiddleware = store => next => action => {
console.log('自定义middleWare2-logger-state', store.getState());
return next(action);
};
export default loggerStateMiddleware;
const store = createStore(rootReducer,applyMiddleware(loggerStateMiddleware));
中间件的原理
首先从使用中间件的语法入手:
js
const store = createStore(
rootReducer,
applyMiddleware(middleware1, middleware2)
);
那么接下来看看createStore
做了什么呢?简化版createStore
如下:
js
function createStore(reducer, preloadedState, enhancer) {
/**createStore接收三个参数
* 第一个参数是 rootReducer,用于处理状态变化,
* 第二个参数是可选的初始状态(preloadedState),
* 第三个参数是中间件链enhancer。
*/
// 如果传入了 enhancer,则使用 enhancer 增强 createStore
if (typeof enhancer === 'function') {
return enhancer(createStore)(reducer, preloadedState);
}
// 内部状态
let currentState = preloadedState;
let currentReducer = reducer;
let listeners = [];
// 获取当前状态
function getState() {
return currentState;
}
// 触发 action,并更新状态
function dispatch(action) {
currentState = currentReducer(currentState, action);
// 通知所有监听器(订阅者)
listeners.forEach(listener => listener());
return action;
}
// 订阅状态变化
function subscribe(listener) {
listeners.push(listener);
// 返回一个取消订阅的函数
return function unsubscribe() {
listeners = listeners.filter(l => l !== listener);
};
}
// 初始化 store
dispatch({ type: '@@redux/INIT' });
// 返回 store 对象
return {
getState,
dispatch,
subscribe,
};
}
知道了createStore
的基本处理,接下来看看applyMiddleware
做了什么:
由下可以看出:
applyMiddleware
内部也重写了dispatch
js
function applyMiddleware(...middlewares) {
// 返回一个高阶函数,接收 createStore 作为参数
return createStore => reducer => {
// 创建原始的 Redux store
const store = createStore(reducer);
// 初始化 dispatch 函数,指向原始的 store.dispatch
let dispatch = store.dispatch;
// middlewareAPI 包含 getState 和 dispatch 方法
const middlewareAPI = {
getState: store.getState,
dispatch: action => dispatch(action)
};
// 将每个中间件传入 middlewareAPI,得到包装后的中间件函数
const chain = middlewares.map(middleware => middleware(middlewareAPI));
// compose 函数用于将多个函数从右到左组合起来
dispatch = compose(...chain)(store.dispatch);
// 返回一个增强版的 store,其中的 dispatch 已经被中间件包装
return {
...store,
dispatch
};
};
}
// compose 函数用于将多个函数组合成一个函数
function compose(...funcs) {
return arg => funcs.reduceRight((composed, f) => f(composed), arg);
}
接下来一张图就能说清整体的流程了: