NgRx — это фреймворк для управления состоянием в Angular-приложениях, основанный на принципах Redux и реактивного программирования с использованием RxJS. Это решение для сложных enterprise-приложений с интенсивным взаимодействием с данными.
Единственный источник истины для всего состояния приложения. Представляет собой иммутабельный объект.
Описания событий, которые происходят в приложении. Это простые объекты с типом и опциональными данными.
export const loadProducts = createAction('[Products Page] Load Products');
export const loadProductsSuccess = createAction(
'[Products API] Products Loaded Success',
props<{ products: Product[] }>()
);
Чистые функции, которые определяют как состояние изменяется в ответ на действия.
const productReducer = createReducer(
initialState,
on(loadProductsSuccess, (state, { products }) => ({
...state,
products,
loaded: true
}))
);
Функции для извлечения конкретных частей состояния из хранилища.
export const selectAllProducts = createSelector(
selectProductsState,
state => state.products
);
Механизм для обработки side-эффектов (API-вызовы и т.д.) в изолированном виде.
loadProducts$ = createEffect(() =>
this.actions$.pipe(
ofType(loadProducts),
mergeMap(() => this.productsService.getAll().pipe(
map(products => loadProductsSuccess({ products })),
catchError(error => of(loadProductsFailure({ error })))
)
)
);
export interface AppState {
products: ProductsState;
cart: CartState;
}
export const reducers: ActionReducerMap<AppState> = {
products: productsReducer,
cart: cartReducer
};
export const metaReducers: MetaReducer<AppState>[] = !environment.production
? [logger]
: [];
@Component({
selector: 'app-products',
template: `
<div *ngFor="let product of products$ | async">
{{ product.name }}
<button (click)="addToCart(product)">Add to Cart</button>
</div>
`
})
export class ProductsComponent {
products$ = this.store.select(selectAllProducts);
constructor(private store: Store<AppState>) {}
ngOnInit() {
this.store.dispatch(loadProducts());
}
addToCart(product: Product) {
this.store.dispatch(addItemToCart({ item: product }));
}
}
NgRx — это мощное решение, которое при правильном применении значительно упрощает разработку и поддержку сложных Angular-приложений, но требует взвешенного подхода к внедрению.