ngrx

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

@ngrx/store, @ngrx/effects, @ngrx/entity, @ngrx/signals

@ngrx/store, @ngrx/effects, @ngrx/entity, @ngrx/signals

Version: 19.0.0 (2025) Tags: State Management, Redux, Reactive, Store, Effects
References: Docs — guides, API • GitHubGitHub Issues
版本: 19.0.0 (2025年) 标签: State Management, Redux, Reactive, Store, Effects
参考: 文档 — 指南、API • GitHubGitHub Issues

API Changes

API变更

This section documents recent version-specific API changes.
  • NEW: NgRx Signal Store — Modern, lightweight state management with Signals API, reducing boilerplate significantly source
  • NEW: Functional Effects — Modern approach to creating effects using functional programming patterns
  • NEW:
    withEntities
    — Entity management for Signal Store, simplifies CRUD operations on collections
  • NEW:
    @ngrx/data
    — Simplifies entity CRUD operations with automatic HTTP integration
  • DEPRECATED: Classic NgRx patterns — Consider migrating to Signal Store for new projects
本部分记录了近期版本对应的API变动。
  • 新增:NgRx Signal Store — 基于Signals API的现代化轻量级状态管理方案,大幅减少模板代码 来源
  • 新增:函数式Effects — 使用函数式编程模式创建effects的现代化方案
  • 新增:
    withEntities
    — 面向Signal Store的实体管理能力,简化集合的CRUD操作
  • 新增:
    @ngrx/data
    — 通过自动集成HTTP能力简化实体CRUD操作
  • 已废弃:传统NgRx模式 — 新项目建议迁移至Signal Store

Best Practices

最佳实践

  • Use NgRx Signal Store for new projects — Combines NgRx structure with Signals performance
ts
import { signalStore, withState, withMethods, withHooks } from '@ngrx/signals';

export const AuthStore = signalStore(
  withState({ user: null, isAuthenticated: false }),
  withMethods((store, authService = inject(AuthService)) => ({
    login(credentials: Credentials) {
      authService.login(credentials).pipe(
        tap(user => store.user.set(user))
      ).subscribe();
    }
  })),
  withHooks({
    onInit() {
      // Initialize store
    }
  })
);
  • Use Entity Adapter for collections — Simplifies CRUD operations on entity collections
ts
import { createEntityAdapter, EntityState } from '@ngrx/entity';

export interface Product extends EntityState<Product> {
  // Additional state properties
}

export const adapter = createEntityAdapter<Product>({
  selectId: (product) => product.id
});
  • Keep reducers pure and synchronous — Never perform async operations in reducers
  • Use Effects for side effects — Handle HTTP calls, navigation, and other async operations in effects
  • Use strongly typed actions — Create action groups for better type safety
  • Normalize state for complex data — Store entities in dictionaries indexed by ID
  • Use memoized selectors — Prevent unnecessary re-computations
  • Use
    ChangeDetectionStrategy.OnPush
    — Work well with reactive state
  • 新项目优先使用NgRx Signal Store — 结合了NgRx的架构优势与Signals的高性能
ts
import { signalStore, withState, withMethods, withHooks } from '@ngrx/signals';

export const AuthStore = signalStore(
  withState({ user: null, isAuthenticated: false }),
  withMethods((store, authService = inject(AuthService)) => ({
    login(credentials: Credentials) {
      authService.login(credentials).pipe(
        tap(user => store.user.set(user))
      ).subscribe();
    }
  })),
  withHooks({
    onInit() {
      // Initialize store
    }
  })
);
  • 集合数据使用Entity Adapter — 简化实体集合的CRUD操作
ts
import { createEntityAdapter, EntityState } from '@ngrx/entity';

export interface Product extends EntityState<Product> {
  // Additional state properties
}

export const adapter = createEntityAdapter<Product>({
  selectId: (product) => product.id
});
  • 保证reducer为纯函数且同步执行 — 绝对不要在reducer中执行异步操作
  • 副作用交由Effects处理 — 在effects中处理HTTP调用、路由跳转以及其他异步操作
  • 使用强类型化的action — 创建action分组以获得更好的类型安全
  • 复杂数据的状态做扁平化处理 — 实体以ID为键存储在字典结构中
  • 使用记忆化选择器 — 避免不必要的重复计算
  • 使用
    ChangeDetectionStrategy.OnPush
    — 可与响应式状态良好配合