前置き
AsyncPipe使った方が良いよ!っていうことを最近教えてもらったので、色々調べてまとめてみました。
AngularとかAsyncPipeとかRxJSについて一応知ってはいるけど、まだあまり使ったことないっていう方向けなので、
RxJSって何?Observableって何?って方は、先に RxJS公式ドキュメントなどをご参照ください🎅
なんでSubscribe使わないの?
"NO SUBSCRIBING MEANS... NO UNSUBSCRIBING!" (参考動画)
(SUBSCRIBEしないってことは... UNSUBSCRIBEしないでいいってことじゃん!)
AsyncPipeを使うと自分でUnsubscribeする必要がなくなるので便利+Unsubscribeし忘れもなくなります🎅🎄
もうちょっと説明します
まずはsubscribeを使って書いてみます。
import { Component, OnDestroy, OnInit } from '@angular/core';
import { Subscription } from 'rxjs';
import { UserService } from '../user.service';
@Component({
selector: 'app-subscribe',
template: `
ng-container(*ngFor="let user of users")
h1 {{ user.name }}
h2 {{ user.email_address }}
`,
})
export class SubscribeComponent implements OnInit {
users: User[];
private subscription: Subscription;
constructor(private userService: UserService) {}
// AngularのComponentインスタンスが作成されるタイミングと、
// 実際にComponentがビューに配置されるタイミングは一致しないため、
// subscribeはconstructor内ではなく、ngOnInit以降で呼び出した方が良いそうです🤶
ngOnInit() {
this.subscription = this.userService.users$.subscribe((userData) => this.userData = userData);
ngOnDestroy() {
this.subscription.unsubscribe();
}
}
次に、AsyncPipeありバージョン
import { Component } from '@angular/core';
import { UserService } from '../user.service';
@Component({
selector: 'app-async-pype',
template: `
ng-container(*ngIf="users$ | async as users")
div(*ngFor="let user of users")
h1 {{ user.name }}
h2 {{ user.email_address }}
`,
changeDetection: ChangeDetectionStrategy.OnPush
})
export class SubscribeComponent {
users$: Observable<User[]> = this.userStoreService.users;
constructor(private userService: UserService) {}
}
すっきりしましたね!
AsyncPipeを使った場合、ngOnInitライフサイクルフックは必要なく、必要なObservableデータをプロパティに置くだけでOKです!(データの変更検知、反映も同じようにしてくれます!)
Subscribeをすると、Unsubscribeをしないとメモリリークが起きる可能性があるみたいなんですが、AsyncPipeを使うとコンポーネントが破棄されるタイミングで自動的にUnsubscribeしてくれるので、手動でUnsubscribeする必要がなくなります🤶🎄
**また、ChangeDetectionStrategy.OnPushというものが使えるようになり、下記項目発生時のみ変更を検知するようになるため、Change Detectionサイクルを最小限に抑えることができ、パフォーマンスが上がるそうです。
- @Inputプロパティに変更があった時
- イベント発生時
- 指定したObservableが流れた時(今回の場合は"users$")**
参考記事
[combineLatestドキュメント] (https://rxjs-dev.firebaseapp.com/api/index/function/combineLatest)
AsyncPipeドキュメント
🎅🎄🎅🎄メリークリスマス🎅🎄🎅🎄