如何解决ngrx无状态组件+与商店交互
是否可以编写与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
。基本上,如果您可以按照概述进行钻探,那么单元测试和重构将更加容易。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。