简介
在现代的前端开发中,数据是至关重要的一部分。但是当应用变得更加复杂时,数据的管理会变得非常困难。为了解决这个问题,我们可以使用类似于 Flux 和 Redux 的数据管理框架。在 Angular 应用中,NgRx 是最常用的框架之一。
NgRx 是一个基于 Redux 的状态管理库,专门为 Angular 应用程序设计。使用 NgRx,可以轻松地组织代码并跟踪应用程序中的状态变化,使得代码更可维护和可测试。
本文将详细介绍 NgRx 的基本功能,以及在 Angular 应用程序中使用 NgRx 的最佳实践。我们将使用一个简单的 Angular 应用程序作为示例并提供一些完整的代码。
NgRx: 状态管理的基础
NgRx 与 Redux 有很多共同点,它们的目标都是在应用程序中实现可预测的状态管理。NgRx 增强了 Redux 库的功能,使其可以更好地与 Angular 库协同工作,同时还提供了更多的开箱即用的功能。
NgRx 通过 Store 对象管理应用程序的状态。该对象可以提供专门用于状态更新和查询的方法。Redux 的 Store 对象被认为是不可变的,它的状态只能通过 Dispatch 对象来更改,这样可以保证状态的可预测性和不变性。
在 NgRx 中,用户定义了一个或多个 Action 对象来描述对状态进行的更改。Action 对象会传递给 Store,Store 会自动执行相应的 Reducer 函数来更新状态。Reducer 函数返回一个新的状态对象,而不是在状态对象上进行修改。
NgRx: 核心概念
在了解 NgRx 的基本概念之后,我们需要熟悉一些重要的概念,以便更好地理解数据管理流程。
Action
Action 是应用程序中对状态进行更改的描述。每个 Action 都包含一个 type 属性,用于唯一标识该操作的类型,以及一个 payload 属性,用于传递操作所需的任何数据。
在本示例中,我们将为一个小的 TODO 应用程序定义以下两个 Action。
-- -------------------- ---- ------- ------ ----- -------- - ------- --- ------ ------ ----- ----------- - ------- ------ ------ ------ ----- ------- ---------- ------ - -------- ---- - --------- ------------------ -------- - ----- ------ -- -- - ------ ----- ---------- ---------- ------ - -------- ---- - ------------ ------------------ -------- - --- ------ -- -- - ------ ---- ----------- - ------- - -----------
Reducer
一个 Reducer 是一个纯函数,它根据给定的 Action 来更新应用程序的状态。它接收一个当前状态的参数和一个 Action 对象,并返回一个新的状态对象。它不应该修改原始状态,而是应该返回一个新的对象,以避免状态的意外更改。
例如,以下代码演示了如何通过在 Reducer 中使用带有 TypeScript 的模式匹配技术来更新 TODO 应用程序的状态。
-- -------------------- ---- ------- ------ - --------- ------------ ----------- - ---- ----------------- ------ --------- ----- - ------ ------- - ------ ----- ------------- ----- - - ------ -- -- ------ -------- ------------- - ------------- ------- ------------- ----- - ------ ------------- - ---- --------- - ----- ------- - - --- ------------------ - -- ----- ------------------- -- ------ - --------- ------ ---------------- -------- -- - ---- ------------ - ------ - --------- ------ ----------------------- -- ------- --- ------------------ -- - -------- - ------ ------ - - -
Store
Store 是一个状态集合,可以将其视为状态容器。我们使用 {@link @ngrx/store} 库来创建 Store 实例。Store 提供了几个与状态交互的方法,包括 dispatch() 和 select()。
当组件需要对状态进行更改时,它会将适当的 Action 对象传递给 dispatch() 方法。这个 Action 对象会被传递给 Reducer,Reducer 会检查 Action 类型并相应地更新状态。
例如,以下代码演示了如何在 Angular 组件中使用 NgRx 中的 Store 对象。在这个简单的示例中,我们要将 Todo 添加到我们的应用程序中。
-- -------------------- ---- ------- ------ - --------- - ---- ---------------- ------ - ----- - ---- -------------- ------ - ------- - ---- ----------------- ------ - -------- - ---- -------------- ------------ --------- --------------- --------- - ----- ---------------------- ------ ----------- ------------------ - ----- ------------------ -- ----------- ------------- ------- - -- ------ ----- ---------------- - ---- - --- ------------------- ------ ---------------- -- ---------- - ----- ---- - - ----- --------- -- ----------------------- --------- ----- --------- ---- --------- - --- - -
Selector
随着应用程序变得更大,访问和组织状态变得更加困难。NgRx 中的 Selector 可以帮助应用程序管理更复杂的状态。一个 Selector 是一个函数,它从 Store 中选择给定的状态切片。
例如,以下示例演示如何选择我们的 TODO 应用程序中的 todos 状态切片。
import { createSelector } from '@ngrx/store'; import { AppState } from './app.state'; export const selectTodos = createSelector( (state: AppState) => state.todos, todos => todos );
NgRx: 最佳实践
现在我们已经了解了 NgRx 基本概念以及一些重要的概念,让我们来看看 Angular 应用程序中使用 NgRx 的最佳实践。
将数据加载到 Store 中
将数据加载到 NgRx Store 中是管理应用程序状态的第一步。一种常见的模式是在组件中使用 Resolver 解析器来加载初始数据。Resolver 可以在路由导航期间异步预取数据,并将其放置在 Store 中,以便所有组件都可以访问它。这样可以避免在组件中重复加载数据的问题。
避免组件中的副作用
在组件中使用副作用是不好的设计。在 NgRx 中,我们使用 Effects 状态管理器来避免在组件中发出副作用。Effects 可以处理异步操作,并发出一个或多个 Action 来更新 Store 中的状态。这样就可以将组件与异步副作用分离,并且状态管理更加可靠。
减少 Store 的冗余性
Store 是整个应用程序的中心,设计良好的应用程序应该尽可能减少冗余的状态。如果在 Store 中存在重复的状态,那么更新状态会变得非常麻烦,而且可能会导致应用程序的性能下降。
对于其中某些状态,可以使用 @ngrx/entity 库实现更好的表现和开发体验。
以下代码片段演示了 @ngrx/entity 的用法:
-- -------------------- ---- ------- ------ - ------------ -------------- ------------------- - ---- --------------- ------ - ---- - ---- --------------- ------ - ------------ --------- ----------- - ---- ----------------- ------ --------- ----- ------- ----------------- -- ------ -------- --------------- ------ ------ - ------ ----- - ------ -------- ------------- ----- -- ------ ------ - ------ ----------------------------- - ------ ----- -------- ------------------- - --------------------------- --------- ------------- ------------- ---------- --- ------ ----- ------------- ----- - ---------------------------- ------ -------- ------------- - ------------- ------- ------------- ----- - ------ ------------- - ---- --------- - ------ ----------------------------------- ------- - ---- ------------ - ------ ------------------------------------ ------- - -------- - ------ ------ - - -
示例代码
最后,我们为你提供了一个完整的示例应用程序,该应用程序使用 NgRx 来管理 TODO 应用程序的状态。以下代码片段包含 todo.actions.ts、todo.reducer.ts 和 app.state.ts。
-- -------------------- ---- ------- -- --------------- ------ - ------ - ---- -------------- ------ - ---- - ---- --------------- ------ ----- -------- - ------- --- ------ ------ ----- ----------- - ------- ------ ------ ------ ----- ------- ---------- ------ - -------- ---- - --------- ------------------ -------- - ----- ---- -- -- - ------ ----- ---------- ---------- ------ - -------- ---- - ------------ ------------------ -------- - --- ------ -- -- - ------ ---- ----------- - ------- - -----------
-- -------------------- ---- ------- -- --------------- ------ - ------------ -------------- ------------------- - ---- --------------- ------ - ---- - ---- --------------- ------ - ------------ --------- ----------- - ---- ----------------- ------ --------- ----- ------- ----------------- -- ------ -------- --------------- ------ ------ - ------ ----- - ------ -------- ------------- ----- -- ------ ------ - ------ ----------------------------- - ------ ----- -------- ------------------- - --------------------------- --------- ------------- ------------- ---------- --- ------ ----- ------------- ----- - ---------------------------- ------ -------- ------------- - ------------- ------- ------------- ----- - ------ ------------- - ---- --------- - ------ ----------------------------------- ------- - ---- ------------ - ------ ------------------------------------ ------- - -------- - ------ ------ - - -
// app.state.ts import { Todo } from './todo/model'; export interface AppState { todos: Todo[]; }
总结
NgRx 使状态管理变得更加容易,可预测性,可维护性。它提供了类似于 Flux 和 Redux 的方法来管理 Angular 应用程序中的状态,使得开发者可以更好地组织和管理数据。但是,了解 NgRx 的基础知识和最佳实践是非常重要的,以便创建高质量的应用程序。在使用 NgRx 时,您需要关注数据加载,组件副作用,和减少 Store 的冗余。最后,我们提供了一个完整的示例应用程序,希望可以为你提供一个好的学习参考。
来源:JavaScript中文网 ,转载请注明来源 https://www.javascriptcn.com/post/64893d3548841e989478aed6