前言
Redux 是一种用于管理 JavaScript 应用程序状态的强大工具。它遵循单向数据流的模式,允许开发人员将应用程序状态存储在一个可预测的数据容器中。Redux 源码的解读对于深入理解 Redux 的工作原理至关重要。
在本文中,我们将深入探讨 Redux 源码的每个方面,包括框架结构、Redux 中的重要概念和函数、以及如何使用 Redux 构建可伸缩的应用程序。
框架结构
Redux 是一个相对简单的库,由三个主要的组件构成:store、reducers 和 actions。
- Store:存储应用程序的状态数据的容器。它是单一可变状态的唯一来源,并通过订阅机制让组件可以获取到状态更改的通知。
- Reducers:一个纯函数,负责将先前的状态和一个动作作为输入,并返回一个新的状态。Reducers 是单向的,你不能从中返回副作用(例如,不应该改变输入或输出参数或执行非纯的 API 调用)。
- Actions:描述发生在应用程序中的事件的对象。它们包含应用程序必要的元数据,例如事件类型和任何必需的数据。
通过这三个组件,Redux 管理应用程序状态的流程如下:
1. 组件调用 store.dispatch(action) 发出一个 action。 2. Redux 通知所有注册的 reducers 尝试匹配这个 action,执行对应的 Reducer,生成一个新的状态。 3. Redux 触发订阅的回调函数,以通知组件状态的变化。
关键函数
createStore
createStore 函数是 Redux 源码中最重要的函数之一。它将 Reducers 和初始化状态结合在一起,创建 Redux Store 对象。
-- -------------------- ---- ------- -------- -------------------- --------------- --------- - ----- ------ - --------- ---------- --------- --------------- --------------- ---------- - -
参数
- reducer (Function):一个接受两个参数的函数。它的返回值将成为新的应用程序状态,每当一个 action 被 dispatched 时,就会调用该函数。 reducer 必须是纯函数。
- preloadedState:初始状态。作为第一次触发 dispatch 的参数传递给 reducer。
- enhancer (Function):一个 store 增强器。可以使用 applyMiddleware() 实现自定义中间件,打印状态的 logger,持久化 state 的方法等。
返回值
- dispatch(Function):发送一个 action。是改变 state 的唯一途径,且是同步的操作。
- subscribe(Function):添加一个 change listener。
- getState(Function):返回应用程序的当前状态。
- replaceReducer(Function):替换 store 当前使用的 reducer。
[$$observable]
(Symbol):如果源 Store 能够支持 Observable 接口,则可以使用此属性将 Store 转换为可观察对象。
applyMiddleware
applyMiddleware 是一个 store enhancer 函数,用于将自定义中间件应用于 Redux Store。
-- -------------------- ---- ------- -------- ------------------------------- - ------ ----------- -- --------- -- - ----- ----- - -------------------- --- -------- - -------------- ----- ----- - -------------------------- -- ------------ --------- --------------- --------- -------- -------- -- ---------------- -------- --- -------- - --------------------------------- ------ - --------- -------- - - -
参数
- middlewares:一个返回中间件的函数集合。
返回值
- createStore:参数列表中的第一个参数
- 返回函数:一个增强了 store 的函数。
bindActionCreators
bindActionCreators 函数可以将 action creator 转化为带有 dispatch 方法的函数集合。
-- -------------------- ---- ------- -------- ---------------------------------- --------- - -- ------- -------------- --- ----------- - ------ --------------------------------- --------- - -- ------- -------------- --- -------- -- -------------- --- ----- - ----- --- ------ ------------------- -------- -- ------ -- - --------- ------- -------- -- -------------- --- ---- - ------ - ------ -------------- -- - - ---- --- ----- ------- -------------- ----- ------- -- ------- - -- -------------- ------- - - ----- ---- - --------------------------- ----- ------------------- - -- --- ---- - - -- - - ------------ ---- - ----- --- - ------- ----- ------------- - ------------------- -- ------- ------------- --- ----------- - ------------------------ - -------------------------------- --------- - - ------ ------------------- -
参数
- actionCreators: 一个 action creator 的集合。可以是函数,也可以是对象。
- dispatch: 一个 store 的 dispatch 函数。
返回值
- 一个新的函数集合,其中包含与原始传入参数中的函数一一对应的函数。每个函数都已经绑定到了指定的 dispatch 函数上。
combineReducers
combineReducers 函数用于将与应用程序状态相关的多个 reducer 合并为一个总的 reducer。
-- -------------------- ---- ------- -------- ------------------------- - ----- ----------- - --------------------- ----- ------------- - -- --- ---- - - -- - - ------------------- ---- - ----- --- - -------------- -- ------- ------------- --- ----------- - ------------------ - ------------- - - ----- ---------------- - -------------------------- ------ -------- ----------------- - --- ------- - --- ---------- - ----- ----- --------- - -- --- ---- - - -- - - ------------------------ ---- - ----- --- - ------------------- ----- ------- - ------------------ ----- ------------------- - ---------- ----- --------------- - ---------------------------- ------- -------------- - --------------- ---------- - ---------- -- --------------- --- ------------------- - ------ ---------- - --------- - ----- - -
参数
- reducers:一个对象,其中 key 为状态部分的名称,值为处理该状态部分变化的 reducer。它允许将多个 reducer 合并为单个 reducer。
返回值
- 单个 reducer 函数:这个函数接受两个参数,第一个是当前状态的值,第二个是一个 dispatch 函数。
示例代码
下面是一个示例代码,展示如何使用 Redux 管理状态。
首先,安装 redux 和 react-redux:
npm install --save redux react-redux
其次,创建三个基础组件:一个 reducer,一个 action,以及一个初始化 store。
reducer.js
-- -------------------- ---- ------- ------ - ----------- - ---- ---------- ----- -------------- - ------ - --- ------- -- - ------ ------------- - ---- ------------ ------ -------------- -------- ------ ----- - - ------ ------- --------------
action.js
export const SET_MESSAGE = 'SET_MESSAGE' export const setMessage = message => ({ type: SET_MESSAGE, payload: message })
store.js
import { createStore } from 'redux' import messageReducer from './reducer' const store = createStore(messageReducer) export default store
然后,在 React 组件中引入 react-redux:
App.js
-- -------------------- ---- ------- ------ ----- ---- ------- ------ - ------- - ---- ------------- ------ - ---------- - ---- ---------- ----- --- ------- --------------- - ------------------ - ------------ ---------- - - -------- -- - - ------------ - ----- -- - ---------------------- ----------------------------------------- - ------------ - ----- -- - --------------- -------- ------------------ -- - -------- - ------ - ----- ----- ----------------------------- ------ ----------- -------------------------- ---------------------------- -- ------- ----------------------------- ------- --------------------------- ------ - - - ----- --------------- - ----- -- -- -------- ----- -- ----- ------------------ - - ---------- - ------ ------- ------------------------ ------------------------
在 mapDispatchToProps 中,我们将 action creator 的值设置为 setMessage,这样就可以调用 store.dispatch(setMessage()) 函数来更新组件的状态。
最后,将 store 提供给组件根节点:
index.js
-- -------------------- ---- ------- ------ ----- ---- ------- ------ -------- ---- ----------- ------ - -------- - ---- ------------- ------ ----- ---- --------- ------ --- ---- ------- ---------------- --------- -------------- ---- -- ------------ ------------------------------- -
结论
Redux 源码本质上是一个很小的库,缺乏许多高级功能。但是,它的核心理念和关键函数可以应用于任何规模的应用程序。可以通过尝试更复杂的使用场景,例如异步 action、自定义中间件、代码拆分和热装载等来提高自己的 Redux 技能。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/676f6cd8e9a7045d0d72b471