Angular State Management is Changing: Part 2 (And NgRx Isn’t What You Think Anymore)
Angular State Management is Changing: Part 2 (And NgRx Isn’t What You Think Anymore)
Angular 状态管理正在发生变化:第二部分(NgRx 已不再是你以为的那样)
Let’s be honest, most Angular apps didn’t fail because of “bad state management”. If you are new to state management then revisit my part 1. They failed because we kept using NgRx for problems it was never meant to solve. And now with Signals, that mistake is getting harder to justify. 老实说,大多数 Angular 应用的失败并不是因为“状态管理不善”。如果你是状态管理的新手,请先回顾我的第一部分。它们失败的原因是我们一直在用 NgRx 去解决它本不该解决的问题。而现在有了 Signals,这种错误就更难自圆其说了。
Why NgRx Was Introduced
为什么引入 NgRx
NgRx was introduced to solve architectural problems that services could not handle in large applications. It brought a strict Redux-style model with a single source of truth and predictable state flow. Every state change followed a defined path: actions were dispatched, reducers updated state, selectors derived data, and components subscribed to changes. This made state changes explicit, traceable, and easier to debug in large applications. NgRx solved the problem of structure, predictability, and scalability. 引入 NgRx 是为了解决大型应用中 Service 无法处理的架构问题。它带来了一种严格的 Redux 风格模型,具有单一事实来源和可预测的状态流。每一次状态变更都遵循既定路径:分发 Action、Reducer 更新状态、Selector 派生数据、组件订阅变更。这使得大型应用中的状态变更变得明确、可追溯且易于调试。NgRx 解决了结构、可预测性和可扩展性的问题。
The Problem with NgRx
NgRx 的问题
While NgRx solved architectural issues, it also introduced complexity. Even simple state updates required multiple steps: actions, reducers, selectors, and sometimes effects. This resulted in a lot of boilerplate code for simple features. In many cases, developers were using NgRx even when the problem did not require that level of structure. This made small and medium applications unnecessarily complex. NgRx solved structure, but often added overhead for simplicity. 虽然 NgRx 解决了架构问题,但也引入了复杂性。即使是简单的状态更新也需要多个步骤:Action、Reducer、Selector,有时还需要 Effect。这导致简单的功能产生了大量的样板代码。在许多情况下,即使问题并不需要那种程度的结构,开发人员也在使用 NgRx。这使得中小型应用变得不必要地复杂。NgRx 解决了结构问题,但往往以牺牲简洁性为代价增加了开销。
Enter Signals and Signal-Based NgRx
引入 Signals 和基于 Signal 的 NgRx
With Signals and APIs like signalStore and selectSignal, Angular introduces a more direct way of handling state. Instead of always going through actions and reducers, state can now be managed directly using signals inside a store. Components react automatically when state changes, without needing manual subscriptions or selector chains. This significantly reduces boilerplate for simple and feature-level state. At the same time, NgRx is not being removed. It is evolving to integrate Signals so both approaches can coexist.
通过 Signals 以及 signalStore 和 selectSignal 等 API,Angular 引入了一种更直接的状态处理方式。现在,状态可以直接在 Store 中使用 Signal 进行管理,而不必总是经过 Action 和 Reducer。当状态发生变化时,组件会自动响应,无需手动订阅或 Selector 链。这显著减少了简单状态和功能级状态的样板代码。同时,NgRx 并未被移除,它正在演进以集成 Signals,从而使两种方法可以共存。
State Flow Comparison
状态流对比
🟠 Old NgRx Flow (Redux Style) 🟠 旧版 NgRx 流(Redux 风格) Component ↓ Dispatch Action ↓ Action ↓ Reducer / Effect ↓ Store Updated ↓ Selector ↓ Observable Stream ↓ Component Subscription ↓ UI Update 组件 ↓ 分发 Action ↓ Action ↓ Reducer / Effect ↓ Store 更新 ↓ Selector ↓ Observable 流 ↓ 组件订阅 ↓ UI 更新
🟢 New Signal-Based NgRx Flow 🟢 新版基于 Signal 的 NgRx 流 Component ↓ Call Store Method ↓ Signal State Update ↓ Computed Signals Recalculate ↓ UI Reacts Automatically 组件 ↓ 调用 Store 方法 ↓ Signal 状态更新 ↓ 计算信号(Computed Signals)重新计算 ↓ UI 自动响应
🟡 Hybrid Flow (Real-world Applications) 🟡 混合流(实际应用场景) Component ↓ Dispatch Action ↓ Effect ↓ API / Async Logic ↓ Signal Store Update ↓ Signals ↓ Computed Signals ↓ UI Updates 组件 ↓ 分发 Action ↓ Effect ↓ API / 异步逻辑 ↓ Signal Store 更新 ↓ Signals ↓ 计算信号 ↓ UI 更新
Effects in a Signal-Based World
基于 Signal 世界中的 Effects
Effects remain an important part of NgRx, especially for: API calls, Authentication flows, Complex async operations, Side effects. The difference is that effects can now directly update Signal-based state instead of always chaining actions. This simplifies async flows while keeping structure where needed. Effects 仍然是 NgRx 的重要组成部分,特别适用于:API 调用、身份验证流程、复杂的异步操作以及副作用。不同之处在于,Effects 现在可以直接更新基于 Signal 的状态,而不必总是链接 Action。这简化了异步流程,同时在需要的地方保留了结构。
Selectors vs Signals
Selectors 与 Signals
Selectors were previously used to derive and access state via observables. Now, Signals reduce the need for selector subscriptions. Instead of: this.store.select(selectUsers), you can use: this.store.selectSignal(selectUsers) or directly consume signal state: users = this.store.users();. This removes subscription management and simplifies component code.
以前,Selectors 用于通过 Observable 派生和访问状态。现在,Signals 减少了对 Selector 订阅的需求。你可以不再使用 this.store.select(selectUsers),而是使用 this.store.selectSignal(selectUsers),或者直接消费 Signal 状态:users = this.store.users();。这消除了订阅管理,并简化了组件代码。
When NgRx Is Less Necessary
何时不再那么需要 NgRx
With Signals, NgRx is no longer required for every type of state. Simple UI state, feature-level state, and small shared state can now be handled using Signals or SignalStore without needing full Redux-style architecture. This is one of the biggest practical changes in Angular state management. 有了 Signals,并非所有类型的状态都需要 NgRx。简单的 UI 状态、功能级状态和小规模共享状态现在可以使用 Signals 或 SignalStore 处理,而无需完整的 Redux 风格架构。这是 Angular 状态管理中最重大的实际变化之一。
When NgRx Still Matters
NgRx 何时依然重要
NgRx is still valuable for: Large-scale applications, Complex state interactions, Multi-feature coordination, Strict debugging and traceability, Heavy asynchronous workflows. Signals do not replace these architectural needs because they focus on reactivity, not orchestration. NgRx 在以下场景中依然具有价值:大型应用、复杂的状态交互、多功能协调、严格的调试和可追溯性、繁重的异步工作流。Signals 并不能取代这些架构需求,因为它们专注于响应式,而非编排。
Why NgRx Is Moving Toward Signals
为什么 NgRx 正在向 Signals 靠拢
According to the official NgRx Signals approach, the goal is to reduce boilerplate, improve developer experience, and modernize state management with Angular’s reactive primitives. NgRx is not being replaced — it is being evolved. 根据官方的 NgRx Signals 方法,其目标是减少样板代码、改善开发体验,并利用 Angular 的响应式原语实现状态管理的现代化。NgRx 没有被取代,而是在演进。
Final Thoughts
结语
Angular state management is no longer about choosing one approach over another. Services handled basic sharing. NgRx introduced structure and predictability. Signals introduce simplicity and reduce unnecessary complexity. Now all three coexist, each solving a different level of problem. Signals are not replacing NgRx. They are simply removing the need to use it everywhere. Angular 状态管理不再是二选一的问题。Service 处理基础共享,NgRx 引入了结构和可预测性,Signals 引入了简洁性并减少了不必要的复杂性。现在这三者共存,各自解决不同层面的问题。Signals 并没有取代 NgRx,它们只是消除了在所有地方都必须使用它的必要性。