前言
Redux 是一个非常流行的 JavaScript 状态管理库,它在 React 项目中扮演着非常重要的角色。本文将对 Redux 的源码进行深入的解析,帮助读者更好地理解其中的机制和设计理念。
Redux 工作流程
Redux 的工作流程可以概括为三个步骤:
- 定义一个初始状态 (Initial State);
- 定义一个更新状态的规则 (Reducer);
- 将初始状态和规则结合,创建一个存储状态的容器 (Store)。
createStore
我们来看一下 Redux 的 createStore
函数,它起到了创建 Redux Store 的作用。它接受一个 Reducer 函数和可选的初始状态作为参数,返回一个能够存储应用中所有 State 的对象。
// javascriptcn.com 代码示例 function createStore(reducer, initialState) { var currentReducer = reducer var currentState = initialState var listeners = [] function getState() { return currentState } function subscribe(listener) { listeners.push(listener) return function unsubscribe() { var index = listeners.indexOf(listener) listeners.splice(index, 1) } } function dispatch(action) { currentState = currentReducer(currentState, action) for (var i = 0; i < listeners.length; i++) { var listener = listeners[i] listener() } return action } dispatch({ type: '@@redux/INIT' }) return { dispatch, subscribe, getState, } }
这个函数主要做了以下几件事情:
- 把参数
reducer
赋值给一个私有变量currentReducer
; - 把参数
initialState
赋值给一个私有变量currentState
; - 把一个空数组赋值给一个私有变量
listeners
,用于存储订阅者的回调函数; - 定义一个
getState
函数,返回currentState
; - 定义一个
subscribe
函数,将listener
展开存入listeners
中,并返回一个取消订阅的函数; - 定义一个
dispatch
函数,将action
对象传入currentReducer
中计算新的 State,执行所有订阅者的回调函数,并返回action
对象; - 第一次
dispatch
一个特殊的@@redux/INIT
action,让currentState
获取到初始状态值。
Reducer
Reducer 是一个纯函数,它的作用是根据 action
和当前 state
计算一个新的 state
,并返回。Reducer 接收两个参数:当前 state
和一个 action
对象。
// javascriptcn.com 代码示例 function reducer(state, action) { switch (action.type) { case 'INCREMENT': return Object.assign({}, state, { count: state.count + 1 }) case 'DECREMENT': return Object.assign({}, state, { count: state.count - 1 }) default: return state } }
在上面的示例中,我们定义了一个 Reducer 函数,它接受一个 state
对象和一个 action
对象。在这个函数中,我们通过检查 action.type
的值来决定对 state
做什么样的修改。
我们在 INCREMENT
和 DECREMENT
两个 case 中返回了计算后的新 state
,而在默认 case 中返回旧 state
,这个旧的 state
会被放回 Store 中。
Action
Action 是一个普通 JavaScript 对象,用于描述将要发生的事件。它是一个纯粹的数据对象,其中必须包含一个 type
属性,用于表示事件类型。
var action = { type: 'INCREMENT', }
在这个示例中,我们定义了一个名为 action
的对象,它有一个 type
属性,我们可以使用 action.type
来获取它的值。
applyMiddleware
applyMiddleware
是 Redux 的一个高级函数,可以添加额外的功能。它需要传入中间件列表,返回一个新的 createStore
函数。
// javascriptcn.com 代码示例 function applyMiddleware(...middlewares) { return function(createStore) { return function(reducer, initialState) { var store = createStore(reducer, initialState) var chain = middlewares.map(function(middleware) { return middleware(store) }) var dispatch = compose(...chain)(store.dispatch) return Object.assign({}, store, { dispatch, }) } } }
在上述代码中,我们通过传入的函数列表来生成 middleware
,然后通过 compose
方法将这些 middleware
组合起来构成一个新的 dispatch
方法。
// javascriptcn.com 代码示例 function compose(...funcs) { if (funcs.length === 0) { return arg => arg } if (funcs.length === 1) { return funcs[0] } return funcs.reduce((a, b) => (...args) => a(b(...args))) }
compose
方法可以将多个函数组合起来,按顺序执行,返回一个新的函数。
总结
在本文中,我们对 Redux 的设计理念、工作原理和源码进行了深入的解析。通过学习 createStore、Reducer、Action 和 applyMiddleware 函数,我们可以更好地理解 Redux 的工作方式,从而更好的应用 Redux 来管理我们的应用状态。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/652a06957d4982a6ebc65161