これは何?
この記事は「24日後に立派なSalesforceエンジニアになるWEBエンジニア Advent Calendar 2022」の10日目の記事です。15日後に立派なSalesforceエンジニアになるために今日はLightning Web Component (LWC)のデコレータについて見ていきたいと思います。
デコレータの種類
公式のドキュメントも用意されていますがLWCには以下の3つのデコレータが用意されており、これらは変数や関数につけることができる。利用する際はjsにインポートしておく必要がある。
import { LightningElement, api, track, wire } from 'lwc';
@api
@api
デコレータは他コンポーネントへ公開するときに使う。
つまり@api
デコレータをつけた変数や関数は他コンポーネントからのアクセスができるようになる。
サンプル
import { LightningElement } from 'lwc';
export default class Parent extends LightningElement {
name = "";
onChange(event){
this.name = event.target.value;
}
}
<template>
<!-- 子コンポーネントに自身のnameを渡す -->
<c-child child-name={name}></c-child>
<lightning-input label="名前" onchange={onChange}></lightning-input>
</template>
import { api, LightningElement } from 'lwc';
export default class Child extends LightningElement {
@api
childName; // この変数を親コンポーネントから変更できるようにしている
}
<template>
<div class="slds-p-horizontal_small">
<p>{childName}</p>
</div>
</template>
@track
@track
デコレータは元々、値が変更されたときに再描画するのに使われる。
サンプル
import { LightningElement, track } from 'lwc';
export default class Test extends LightningElement {
@track fullName = { firstName : '', lastName : '' };
onChange(event) {
this.fullName.firstName = event.target.value;
}
}
<template>
<lightning-card icon-name="standard:account">
<div class="slds-p-horizontal_small">
<p>{fullName.firstName}</p>
<p><lightning-input label="名前" onchange={onChange}></lightning-input></p>
</div>
</lightning-card>
</template>
補足
Salesforce Spring ’20 のリリースでなくても再描画されるようになった。ただリリースノートにあるように@track
をつけないと再描画されないケースがある。
@track
がついていない場合フレームワークは項目自体に新しい値が割り当てられる変更を監視して、変更があった場合はコンポーネントの該当箇所を再描画する。例えば先ほどのサンプルで以下のように変数そのものに新しい値を代入すると再描画が走る。
this.fullName = { firstName : 'John', lastName : 'Doe' };
しかし、以下のように変数の中の1つのプロパティのみ変更された場合は再描画されない。
this.fullName.firstName = 'John';
このような場合も再描画させる必要がある時は @track fullName
のようにデコレータをつけて宣言をする。
@wire
@wire
デコレータはワイヤーサービスからデータの取得をするときに使う。getRecord
やApexのメソッドでデータをとってきてjsの変数に紐づけるケースでよく使う。
サンプル
import { LightningElement, api, wire } from 'lwc';
import { getRecord } from 'lightning/uiRecordApi';
const FIELDS = ['Account.Name'];
export default class Test extends LightningElement {
@api recordId;
@wire(getRecord, { recordId: '$recordId', fields: FIELDS })
account;
}
<template>
<lightning-card icon-name="standard:account">
<template if:true={account.data}>
<div class="slds-p-horizontal_small">
<p>{account.data.fields.Name.value}</p>
</div>
</template>
</lightning-card>
</template>
まとめ
- コンポーネント間でデータをやり取りするのが
@api
- htmlとjs間でデータをやり取りするのが
@track
- jsとApex間もしくはjsと
uiRecordApi.getRecord
間でデータをやり取りするのが@wire
最後に
今日はLWCのデコレータについてそれぞれの使い方をまとめていきました。
明日はLWCのxmlで設定する内容についてみていきます。