Redux源码初探:深入createStore()函数
2024-01-30 02:29:21
Redux 是一个流行的前端状态管理工具,提供了可预测的状态管理方案,帮助开发人员轻松管理复杂应用程序的状态。它具有简单、易于理解的 API,受到许多开发人员的喜爱。
为了更好地理解 Redux 的工作原理和实现细节,本文将深入 Redux 源码,从常用的 API 自顶向下地阅读其源码的实现。首先,让我们从 createStore 函数开始。
1. createStore 函数
createStore 函数是 Redux 的核心函数之一,用于创建 Redux store。Redux store 是一个包含应用程序状态的全局对象,提供了获取、设置和监听状态的接口。
在使用 Redux 时,我们通常通过以下方式创建 store:
const store = createStore(reducer);
其中,reducer 是一个纯函数,用于根据给定的 action 来更新 store 的状态。
createStore 函数接受两个参数:
- reducer:一个纯函数,用于根据给定的 action 来更新 store 的状态。
- initialState:store 的初始状态。
如果未提供 initialState,则 store 的初始状态将被设置为 undefined。
2. createStore 源码解析
createStore 函数的源码如下:
export default function createStore(reducer, initialState, enhancer) {
if (typeof reducer !== 'function') {
throw new Error('Reducer must be a function');
}
if (enhancer) {
return enhancer(createStore)(reducer, initialState);
}
let currentState = initialState;
const listeners = [];
let isDispatching = false;
function dispatch(action) {
if (isDispatching) {
throw new Error('Reducers may not dispatch actions.');
}
try {
isDispatching = true;
currentState = reducer(currentState, action);
} finally {
isDispatching = false;
}
const listenersCopy = listeners.slice();
for (let i = 0; i < listenersCopy.length; i++) {
const listener = listenersCopy[i];
listener();
}
return action;
}
function subscribe(listener) {
listeners.push(listener);
return function unsubscribe() {
const index = listeners.indexOf(listener);
listeners.splice(index, 1);
};
}
function getState() {
return currentState;
}
return {
dispatch,
subscribe,
getState,
};
}
2.1. 参数类型检查
首先,createStore 函数会检查 reducer 是否为一个函数。如果 reducer 不是一个函数,则抛出一个错误。
if (typeof reducer !== 'function') {
throw new Error('Reducer must be a function');
}
2.2. enhancer 的处理
如果 enhancer 参数被提供,则 createStore 函数会调用 enhancer 函数,并将 createStore 函数作为参数传递给 enhancer 函数。
if (enhancer) {
return enhancer(createStore)(reducer, initialState);
}
enhancer 函数是一个高阶函数,它可以增强 createStore 函数的功能。例如,我们可以在 enhancer 函数中添加对 Redux DevTools 的支持。
2.3. store 的创建
如果 enhancer 参数未被提供,则 createStore 函数会创建一个 store 对象。
let currentState = initialState;
const listeners = [];
let isDispatching = false;
currentState 变量存储着 store 的当前状态。listeners 数组存储着所有订阅 store 状态变化的监听器函数。isDispatching 变量用于防止在 dispatch 操作期间再次执行 dispatch 操作。
2.4. dispatch 函数
dispatch 函数用于向 store 派发 action。
function dispatch(action) {
if (isDispatching) {
throw new Error('Reducers may not dispatch actions.');
}
try {
isDispatching = true;
currentState = reducer(currentState, action);
} finally {
isDispatching = false;
}
const listenersCopy = listeners.slice();
for (let i = 0; i < listenersCopy.length; i++) {
const listener = listenersCopy[i];
listener();
}
return action;
}
首先,dispatch 函数会检查 isDispatching 变量是否为 true。如果 isDispatching 为 true,则抛出一个错误,因为在 dispatch 操作期间不允许再次执行 dispatch 操作。
然后,dispatch 函数会将 isDispatching 变量设置为 true,并调用 reducer 函数来更新 store 的状态。
更新完 store 的状态后,dispatch 函数会将 isDispatching 变量设置为 false,并调用所有订阅 store 状态变化的监听器函数。
最后,dispatch 函数会返回 action。
2.5. subscribe 函数
subscribe 函数用于订阅 store 状态变化的监听器函数。
function subscribe(listener) {
listeners.push(listener);
return function unsubscribe() {
const index = listeners.indexOf(listener);
listeners.splice(index, 1);
};
}
subscribe 函数会将监听器函数推入 listeners 数组,并返回一个取消订阅的函数。
取消订阅的函数会从 listeners 数组中删除监听器函数。
2.6. getState 函数
getState 函数用于获取 store 的当前状态。
function getState() {
return currentState;
}
getState 函数会直接返回 currentState 变量。
3. 总结
createStore 函数是 Redux 的核心函数之一,用于创建 Redux store。通过深入解析 createStore 函数的源码,我们可以更好地理解 Redux 的工作原理和实现细节。
在下一篇博文中,我们将继续深入 Redux 源码,探究 store 的其他 API,如 replaceReducer 和 dispatch。