[Redux/Mobx] 说说Redux的实现流程
通过分析redux的几个核心api,来看如何实现redux
store.subscribe: 订阅数据的变化store.dispatch:dispatch后改变state,同时通知store.subscribe函数执行,上面这两个函数可以利用发布-订阅模式store.getState: 通过这个函数直接返回内存中的state变量即可
简单的实现如下
export function createStore(reducer, enhancer) {
if (enhancer && typeof enhancer === 'function') {
const newCreateStore = enhancer(createStore);
const newStore = newCreateStore(reducer);
return newStore;
}
let state; // state记录所有状态
let listeners = []; // 保存所有注册的回调
function subscribe(callback) {
listeners.push(callback); // subscribe就是将回调保存下来
}
// dispatch就是将所有的回调拿出来依次执行就行
function dispatch(action) {
state = reducer(state, action);
for (let i = 0; i < listeners.length; i++) {
const listener = listeners[i];
listener();
}
}
// getState直接返回state
function getState() {
return state;
}
// store包装一下前面的方法直接返回
const store = {
subscribe,
dispatch,
getState
}
return store;
}
export function combineReducers(reducerMap) {
const reducerKeys = Object.keys(reducerMap); // 先把参数里面所有的键值拿出来
// 返回值是一个普通结构的reducer函数
const reducer = (state = {}, action) => {
const newState = {};
for (let i = 0; i < reducerKeys.length; i++) {
// reducerMap里面每个键的值都是一个reducer,我们把它拿出来运行下就可以得到对应键新的state值
// 然后将所有reducer返回的state按照参数里面的key组装好
// 最后再返回组装好的newState就行
const key = reducerKeys[i];
const currentReducer = reducerMap[key];
const prevState = state[key];
newState[key] = currentReducer(prevState, action);
}
return newState;
};
return reducer;
}
// 参数支持多个中间件
export function applyMiddleware(...middlewares) {
function enhancer(createStore) {
function newCreateStore(reducer) {
const store = createStore(reducer);
// 多个middleware,先解构出dispatch => newDispatch的结构
const chain = middlewares.map(middleware => middleware(store));
const { dispatch } = store;
// 用compose得到一个组合了所有newDispatch的函数
const newDispatchGen = Redux.compose(...chain);
// 执行这个函数得到newDispatch
const newDispatch = newDispatchGen(dispatch);
return {...store, dispatch: newDispatch}
}
return newCreateStore;
}
return enhancer;
}
个人简介
我是歌谣,欢迎和大家一起交流前后端知识。放弃很容易,
但坚持一定很酷。欢迎大家一起讨论
浙公网安备 33010602011771号