Redux 是一种流行的 JavaScript 应用程序状态管理工具,用于在整个应用程序中共享状态。Redux 应用程序中的所有状态都存储在单个 JavaScript 对象中,称为"store"。组件通过"dispatch"操作来修改状态,并且它们可以通过"subscribe"方法监听状态的变化。Redux 的主要优势是它提供了一种良好的结构,比如可预测性,可维护性和可测试性等。
在本文中,我们将深入了解 Redux 的工作原理,并编写一个示例 Redux 应用程序来实现一些常见功能,例如在购物平台中添加商品到购物车中。
Redux 原理
Action
Action 是 Redux 中最重要的概念之一。Action 是一个表示应用程序中发生事件的纯 JavaScript 对象。例如,当用户点击“添加到购物车”按钮时,可以创建一个"ADD_TO_CART"动作对象并将其分派到 Redux store 中。
{ type: "ADD_TO_CART", productId: 1, quantity: 1 }
Action 对象具有一个"type"属性,该属性标识此操作的类型。可以根据需要添加其他属性,例如上面的示例中的"productId"和"quantity"属性。
通常使用"action creators"函数来生成 Action 对象。Action creator 的作用是简化 Action 对象的创建,以便我们可以使用正确的类型和属性创建它们而不必手动编写它们的每个细节。
function addToCart(productId, quantity) { return { type: "ADD_TO_CART", productId, quantity }; }
Reducer
Reducer 用于处理 Store 中的 Action 对象。Reducer 是一个纯函数,接收当前的状态和一个 Action 对象,返回一个新的状态。让我们考虑一个简单的示例,使用 Reducer 处理添加到购物车的行动。
首先,我们定义一个初始化状态,该状态包含购物车中的所有商品。
const initialState = { cartItems: [] };
然后,我们编写一个接受旧状态和一个 Action 对象的 Reducer 函数,并返回新状态。在这里,我们检查类型是否为"ADD_TO_CART",如果是,则将新项目添加到购物车对象数组中。
-- -------------------- ---- ------- -------- ----------------- - ------------- ------- - ------ ------------- - ---- -------------- ------ - --------- ---------- - ------------------- - ---------- ----------------- --------- --------------- - - -- -------- ------ ------ - -
在上面的示例中,我们使用了 ES6 解构和展开运算符来轻松地创建新状态。如果"ADD_TO_CART"操作被分派到 Store,则框架会自动调用 Reducer 函数,并将当前状态和 Action 对象作为参数传递。
Store
Store 是状态的集合,包含 Reducer 函数和当前状态。我们使用 createStore 函数来创建 Store。Reducer 函数负责处理 Action,每次处理之后,Store 将更新状态并通知监听器。
import { createStore } from "redux"; const store = createStore(cartReducer);
Store 的主要方法是"dispatch",它接收一个 Action 对象并将其传递给 Reducer 函数。使用这种方法,我们可以使应用程序中的组件更改状态,并且通过 "subscribe" 方法监听状态的变化。
// Dispatch an Action store.dispatch(addToCart(1, 1)); // Subscribe to Store store.subscribe(() => { console.log(store.getState()); });
在上面的示例中,我们使用"addToCart"操作和"dispatch"方法来修改 Store 中的状态。我们还使用"subscribe"方法将一个函数作为监听器添加到 Store 中。在状态更改时,将调用此函数,并且我们可以输出新状态。
构建在线购物平台应用程序
现在,我们已经了解 Redux 的工作原理,让我们编写一个在线购物平台应用程序,将上面的 Redux 概念应用于实际应用。我们要实现的功能有:
- 展示商品列表
- 添加商品到购物车
- 显示当前购物车
准备工作
我们将使用 React JS 库来构建我们的应用程序。 React 具有易于编写且易于扩展的组件模型,适合构建大型应用程序。我们还将使用 react-redux 库作为将 React 应用程序连接到 Redux Store 的桥梁。
首先,让我们安装一些必要的软件包。
$ npm install --save react react-dom redux react-redux
编写应用程序代码
首先,我们将编写一个可重复使用的"Product"组件。该组件将显示产品的名称、描述和价格等信息,并且还有一个"Add to Cart"按钮,用户可以点击该按钮将产品添加到购物车中。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - ------- - ---- -------------- ------ - --------- - ---- ------------------------- ----- ------- - -- -------- --------- -- -- - ------ - ---- -------------------- ---- ------------------- ------------------ -- ---- ------------------------- ----------------------- ---------------------------- --------- ------------------------------- ------- ----------- -- -------------------------- -- ------------- ------ ------ -- -- ------ ------- ------------- - --------- ------------
在上面的代码中,我们使用 connect 函数将组件包装在 HOC 中,以便我们可以访问 Redux Store 中的 action creators。它接受两个参数:mapStateToProps 和 mapDispatchToProps。
mapStateToProps 函数允许我们将 Store 的状态映射到组件的 props,而 mapDispatchToProps 允许我们将 action creators 映射到 props,并以此来操作 Store。
接下来,我们将编写一个简单的购物车组件。该组件会从 Store 中获取购物车项并显示它们。代码如下所示。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ - ------- - ---- -------------- ----- ---- - -- --------- -- -- - ------ - ---- ----------------- ------------- ----------------- --- - -- ------- ---- -- ---------- --------------------- -- - ---- --------------------- ----------------------------- ------------------------ ------ --- ------ -- -- ----- --------------- - ------- -- - ------ - ---------- --------------- -- -- ------ ------- -------------------------------
在上面的代码中,我们使用 mapStateToProps 函数将 Store 中的购物车项映射到组件的 props 中。相反,mapDispatchToProps 允许我们将 action creators 映射到 props,以添加/删除购物车项目等。
最后,我们将构建产品列表组件。该组件会从服务器获取产品列表,将每个产品传递给"Product" 组件,并渲染其内容。
-- -------------------- ---- ------- ------ ------ - --------- - ---- -------- ------ - ------- - ---- -------------- ------ ------- ---- ------------ ------ - ------------- - ---- ---------------------------- ----- ----------- - -- --------- ------------- -- -- - ------------ -- - ---------------- -- ----------------- ------ - ---- ------------------------- ----------------------- -- - -------- ---------------- ----------------- -- --- ------ -- -- ----- --------------- - ------- -- - ------ - --------- -------------- -- -- ------ ------- ------------------------ - ------------- ----------------
在上面的代码中,我们使用 useEffect 钩子调用 fetchProducts 函数,用于从服务器获取产品列表。我们将使用 fetch API 发出网络请求,并将响应数据作为 Store 中的产品列表保存。
最后,我们将在 App.js 文件中组合我们的组件。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ ------------ ------ ---- ---- -------------------- ------ ----------- ---- --------------------------- -------- ----- - ------ - ---- ---------------- ------- ----------------------- ---------- -------- ---------- ----- -- --------- ------ ------------ -- ------- ------ -- - ------ ------- ----
现在我们已经编写了应用程序代码,但这些代码无法正常工作,因为我们缺少 Redux Store 和 Reducers。
添加 Store 和 Reducers
让我们开始编写 Store 和 Reducers 代码。Store.js 文件将包含 Store 对象正确配置和将 Reducers 组合在一起的代码。我们将使用 Redux-thunk 中间件来处理异步网络请求。代码如下所示。
-- -------------------- ---- ------- ------ - ------------ ---------------- --------------- - ---- -------- ------ ----- ---- -------------- ------ - ----------- - ---- ------------------------- ------ - -------------- - ---- ---------------------------- ----- ----------- - ----------------- ---------- ------------ --------- -------------- --- ----- ---------- - -------- ----- ----- - ------------------------ -------------------------------- ------ ------- ------
在上面的代码中,我们使用 Redux 中的 createStore 函数创建 Store 对象。我们使用 Redux 中的 combineReducers 函数将 Reducers 组合在一起,并使用 applyMiddleware 函数将中间件应用于 Store。
编写 Reducers
接下来,我们将编写 Reducers 代码。在我们的应用程序中,我们需要两种 Reducers:一个用于购物车对象,另一个用于产品对象。购物车 Reducer 将处理"ADD_TO_CART"操作,而产品 Reducer 将处理“FETCH_PRODUCTS"操作。这些 Reducers 的初始状态是空数组。
-- -------------------- ---- ------- -- -------------- ----- ------------ - --- ------ ----- ----------- - ------ - ------------- ------- -- - ------ ------------- - ---- -------------- ----- ----- - ---------------- ------ -- -------------- --- ---------------- -- -- ------ -- -- - -- ---- ------- ------ -- ----- ------ -------- ----- ----------- - - ---------------- --------- --------------------- - --------------- -- ------ ------------------ ------- ------------ -------------------- - ---- - ---- - -- ---- ---- --- ----- -- ----- --- --- ---- ------ - --------- - ---------- ----------------- --------- --------------- - -- - -------- ------ ------ - -- -- ----------------- ----- ------------ - --- ------ ----- -------------- - ------ - ------------- ------- -- - ------ ------------- - ---- ----------------- ------ --------------- -------- ------ ------ - --
现在我们完成了 Reducers 示例,让我们添加 Redux Store 的初始化代码在index.js文件中。
-- -------------------- ---- ------- ------ ----- ---- -------- ------ -------- ---- ------------ ------ - -------- - ---- -------------- ------ --- ---- -------- ------ ----- ---- ---------- ---------------- --------- -------------- ---- -- ------------ ------------------------------- --
我们已经编写了应用程序的所有代码,并将其连接到 Redux Store 中。让我们启动开发服务器并查看应用程序是否可用。
$ npm start
结论
在本文中,我们深入了解了 Redux 的工作原理,并编写了一个示例 Redux 应用程序,以实现一些常见功能,例如在购物平台中添加商品到购物车中。
此外,我们还了解了如何使用 React-redux 库将 React 应用程序与 Redux Store 集成,并了解了 Redux 中如何使用 Action、Reducer 和 Store 等核心概念。
学习 Redux 可以提高我们构建大型和复杂的应用程序的技能。最重要的是,Redux 可以提高应用程序的可扩展性、可维护性和可测试性。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/672f0ac8eedcc8a97c8c2e21