Redux 是一个非常流行的状态管理库,它被广泛应用于前端开发中。Redux 的核心是一个独立于任何 UI 库的状态管理器,通过它可以方便地管理应用程序中的数据流。如果您对 Redux 的源码实现有兴趣,或者想在实际项目中应用 Redux,那么这篇文章会对您有所帮助。
Redux 的基本原理
Redux 包含三个核心部分:store、action 和 reducer。
- Store:包含了应用程序的状态。
- Action:是一个简单的对象,描述了发生了什么操作。
- Reducer:描述了如何转换状态,通过 Action 对 Store 进行更新。
Redux 的核心思想是单向数据流。当应用程序的状态发生改变时,Redux 会触发一个 Action,Reducer 根据这个 Action 对 Store 进行更新,并通知 UI 库更新视图。如下图所示:
其中,store 是应用程序的状态仓库,可以通过 createStore 函数创建。Reducer 是一个纯函数,接收一个状态和一个 Action,根据 Action 对状态进行更新并返回一个新的状态。Action 是一个简单的 JavaScript 对象,包含一个 type 属性和一些附加数据。通过调用 Redux 提供的 dispatch 方法,可以向 store 发送一个 Action。UI 库可以通过订阅 store 的改变来更新视图。Redux 还提供了一些中间件来增强其功能,如异步操作和时间旅行等。
Redux 源码解析
Redux 源码主要分为三个部分:store、action 和 reducer。我们把这三个部分分别进行详细的讲解。
1. Store
Store 是应用程序的状态仓库,它是一个包含以下几个重要方法的对象:
- getState():返回当前状态的副本。
- dispatch(action):触发一个 action,更新状态。
- subscribe(listener):订阅改变,当 state 发生变化时调用 listener。
Redux 中 Store 的实现有点像被状态控制的状态机,当用户触发一个 action,Store 就会变化一个状态,Listener 会通过 subscribe 方法监听 Store 的变化,Store 完成 state 状态更新后就会调用 Listener。
-- -------------------- ---- ------- --- ------ --- --------- - --- -------- ---------- - ------ ------ - -------- ---------------- - ----- - -------------- -------- -------------------------- -- ------------ - -------- ------------------- - ------------------------- ------ -------- ------------- - --- ----- - ---------------------------- ----------------------- --- -- -
上述代码是 Redux store 的基础实现。在这段代码中,getState() 方法和 dispatch(action) 方法分别用于获取状态和更新状态。注意到 dispatch 方法中,先通过调用 reducer() 函数,根据 action 和目前的 state 计算出新的 state。然后通知所有的 listener,告诉它们 store 的 state 已经改变。
2. Action
Action 是一个包含 type 属性和一些附加数据的简单 JavaScript 对象。在 Redux 中,Action 必须是一个纯 JavaScript 对象,它不包含方法、类、函数等操作副作用的行为。Action 的 type 属性字符串一般使用常量,用来表示这个 Action 的类型。
-- -------------------- ---- ------- ----- -------- - ----------- --- ------ - - ----- --------- -------- - --- -- ----- ------ ------- -- --
3. Reducer
Reducer 是一个纯函数,接收 state 和一个 action,根据 action 对 state 进行更新,并返回一个新的 state。Reducer 的格式如下:
-- -------------------- ---- ------- -------- -------------- ------- - ------ ------------- - ---- --------- ------ - --------- ------ ---------------- ---------------- -- -------- ------ ------ - -
这里的 reducer 函数接收两个参数,state 储存整个应用程序的状态,action 是一个触发状态变化的对象。它会检查 action 的类型并相应地更改 state,最后返回新的 state。
在实际项目开发中,我们经常将 reducer 拆分成多个子 reducer,然后使用 combineReducers 方法将它们组合在一起。例如,一个使用 combineReducers 组合的 reducer:
import { combineReducers } from "redux"; import visibilityFilter from "./visibilityFilter"; import todos from "./todos"; const rootReducer = combineReducers({ visibilityFilter, todos }); export default rootReducer;
上面的代码演示了如何将两个单独的 reducer 合并成一个主 reducer。通过 combineReducers 函数将两个 reducer 函数合并成一个根 reducer 函数,并将其作为 createStore() 的参数。
Redux 实战开发
现在我们已经了解了 Redux 的源码实现,接下来我们将着重讨论 Redux 实战开发方面的知识。
1. 如何将 Redux 集成到 React 应用中
在实际开发中,Redux 通常作为 React 中的状态管理器使用。为了在 React 应用中使用 Redux,要安装 react-redux 模块并会使用 Provider 和 connect 两种组件。
- Provider:是将 store 给 React 应用的一个组件,它提供 store 中的状态值,使得 app 中 connect 上的子组件都能够获取 store 中的状态了。
- connect:将 React 组件与 Redux store 连接起来的负载高阶组件。
接下来,我们将通过一个TODO List应用程序演示如何集成Redux到我们的React应用中。
首先,在 src 存在一个 store.js(是我们刚刚创建的文件):
import { createStore } from "redux"; import rootReducer from "./reducers/index"; const store = createStore(rootReducer); export default store;
然后,我们在 App.js 文件中引入 import { Provider } from "react-redux";:
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - -------- - ---- -------------- ------ ----- ---- ---------- -------- ----- - ------ - --------- -------------- ----- ---- ---- ------ ----------- -- -
最后,我们需要去创建 reducers 文件夹。在 reducers 文件夹中,我们创建一个 index.js 文件:
-- -------------------- ---- ------- ------ - --------------- - ---- -------- ------ ------------ ---- ------------------ ------ ----------------------- ---- ----------------------------- ----- ----------- - ----------------- ------ ------------- ----------------- ------------------------ --- ------ ------- ------------
现在我们已经将 Redux 集成到我们的 React 应用程序中了。
2. 实现异步操作
Redux 通过中间件解决了一个很重要的问题,即如何处理异步操作。这样,我们可以在 Reducer 中将所有的副作用和异步操作都移除,使得它们更加容易测试和调试。
例如,在实际开发中,我们想从服务器获取数据并在 Redux 仓库中保存。我们可以使用中间件如 redux-thunk 来实现异步操作。
function getDataFromServer() { return dispatch => { return fetch("http://example.com/data") .then(response => response.json()) .then(data => dispatch({ type: "DATA_RECEIVED", data })); }; }
在上面的代码中,getDataFromServer 是一个异步 action,返回一个函数而不是一个对象。这个函数接收 dispatch 函数作为参数,使用 fetch API 异步获取数据并在结果返回时向 redux store 发送一个数据接收 action。
3. 调试 Redux
在这里,我们将介绍几个用于调试 Redux 应用程序的工具。
- redux-devtools:一个强大的浏览器扩展,可以可视化地查看应用程序状态,将 Redux 改变过程可视化和调试。同时,该扩展还提供反应功能和时间旅行功能。
- logger:另一个中间件,可以将所有 Action、Old State、New State 状态等信息输出到控制台上。
import logger from "redux-logger"; const store = createStore(rootReducer, applyMiddleware(logger));
总结
Redux 是一个高效的应用程序状态管理器,可以方便地管理数据流。本文重点介绍了 Redux 源代码以及如何将 Redux 集成到 React 应用程序中。同时,我们还讨论了如何实现异步操作以及使用 Redux 中间件进行调试。这样,我们就学习了大部分 Redux 的知识,并能运用在实际项目开发中。当然, Redux的知识点还是比较多的,需要在开发中去总结和巩固,但展开来说又会非常长,可以单独写一篇文章去详细介绍。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64ae4c2948841e9894a4bc64