ngrx无状态组件+与store交互



是否可以编写与ngrxs存储交互的无状态组件?

我看到的几乎所有示例都没有使用@Input向组件提供状态,而是使用组件内部的this上下文通过选择器检索状态,根据定义,这使组件具有状态。

我不相信ngrx中有任何等效的mapStateToProps,它将允许与商店进行无状态交互。。

我将给您举一个例子。

假设您在应用程序中有一个方面负责显示要销售的产品。

products.component.ts(有状态组件(

product$ = this.store.select(getProducts);
selectedProduct: IProduct;
constructor(private store: Store<ProductsState>) { }
setSelectedProduct(product: IProduct) {
this.selectedProduct = product;
}

products.component.html

<product-details *ngFor="let product of products$ | async"
[product]="product"
(productSelected)="setSelectedProduct($event)"
></product-details>
<div class="selected-product" *ngIf="selectedProduct">
<selected-product
[product]="selectedProduct"
></selected-product>
</div>

product-details.component.ts(无状态,负责监听点击产品并发出点击的项目(

@Input() product: IProduct;
@Output() productSelected = new EventEmitter<IProduct>();
onProductSelect() {
this.productSelected.emit(this.product);
}

product-details.component.html

<div (click)="onProductSelect()">
<div>{{ product.id }}</div>
<div>{{ product.name }}</div>
</div>

selected-product.component.ts(负责在底部显示点击的产品(

@Input() product: IProduct;

selected-product.component.html

<img src="product.img" alt="product image" />
<div class="rating">{{product.rating}}</div>
<div *ngFor="let comment of product.reviewComments"> {{ comment }}</div>

因此,我们的想法是制作一个与您的应用程序相关的功能切片,其中一个组件将是有状态组件(知道如何与商店对话(,即products.component.ts。其他每个视图都会获得输入的数据。

这并不能解决道具钻取的问题,但它将使具有@Input((和@Output(((无状态组件(的组件的单元测试变得容易。

我在React中也使用了这种方法,其中我有一个有状态的组件(带有mapDispatchToProps和mapStateToProps(,然后我将属性作为道具传递,使单元测试更容易。

我也不会认为React中mapStateToProps的子组件是无状态的,因为它们仍然需要知道如何从存储中读取,为此编写单元测试也很困难,因为在进行单元测试时,您必须模拟存储或给定存储。

这种道具钻取的另一个优点是,一个组件负责从存储中读取,如果存储的结构发生变化,则必须在一个组件中进行代码更改,并且属性将像以前一样向下流动。但是,采用每个子组件都具有mapStateToProps的方法,存储结构的更改将在具有mapStateToProps的每个地方进行。

如果你想在多个地方有this.store.select(),那也可以,但这相当于在多个位置有mapStateToProps。基本上,如果您能够按照概述进行道具钻取,那么单元测试和重构会更容易。

最新更新