ワイヤサービスについて

ワイヤサービスは不変のデータストリームをコンポーネントにプロビジョニングします。ストリーム内の各値は、それに先行する値の最新バージョンです。

コンポーネントに渡されるオブジェクトは参照のみです。データを変更するには、コンポーネントで変更するオブジェクトの浅いコピーを作成する必要があります。データを操作する場合、この概念を理解することが重要です。「データフロー」を参照してください。

Important

このワイヤサービスをリアクティブと呼ぶ理由の 1 つは、$ というプレフィックスが付いたリアクティブ変数をサポートしているためです。リアクティブ変数が変更されると、ワイヤサービスが新しいデータをプロビジョニングします。ここで「リクエスト」や「フェッチ」ではなく「プロビジョニング」という言葉を使っているのは、データがクライアントのキャッシュに存在する場合にはネットワークリクエストが関与しないためです。

ワイヤサービスはフローの管理を Lightning Web Components エンジンに委任します。管理の委任は読み取り操作では有益ですが、作成、更新、削除操作ではさほど役に立ちません。開発者であれば、データを変更する操作はすべて自分で管理したいと思うでしょう。作成、更新、および削除の操作を、ワイヤサービスではなく、JavaScript API で実行するのは、そうした理由からです。

Tip

ワイヤサービスの構文 

ワイヤアダプタは、指定インポート構文を使用してインポートします。プロパティまたは関数を @wire でデコレートし、ワイヤアダプタを指定します。各ワイヤアダプタはデータ型を定義します。

ワイヤサービスは、データの不変ストリームをプロビジョニングします。adapterConfig オブジェクトの内容が同じであっても、データが同じになるかどうかは保証されません。

1// Syntax
2import { adapterId } from 'adapterModule';
3@wire(adapterId, adapterConfig)
4propertyOrFunction;
  • adapterId (ID) — ワイヤアダプタの ID。

  • adapterModule (文字列) — ワイヤアダプタ関数が含まれるモジュールの ID。形式は namespace/moduleName です。形式に注意してください。JavaScript モジュールをインポートするには、lightning-ui-*-api ではなく lightning/ui*Api を使用します。

  • adapterConfig (オブジェクト) — ワイヤアダプタ固有の設定オブジェクト。設定オブジェクトのプロパティ値は、文字列か、または @salesforce/schema からインポートされるオブジェクトや項目への参照です。{adapterConfig} オブジェクトのプロパティは未定義にはできません。プロパティが未定義である場合、サービスはデータをプロビジョニングしません。renderedCallback() 内のワイヤアダプタ設定オブジェクトプロパティを更新しないでください。無限ループが発生する可能性があります。

  • propertyOrFunction — ワイヤサービスからデータのストリームを受信する非公開のプロパティまたは関数。プロパティが @wire でデコレートされている場合、結果はそのプロパティの data プロパティまたは error プロパティに返されます。関数が @wire でデコレートされている場合、結果は data プロパティと error プロパティを持つオブジェクトで返されます。

    Note

data プロパティと error プロパティは、API のハードコードされた値です。これらの値を使用する必要があります。

:::

Salesforce オブジェクトと項目への参照のインポート 

lightning/ui*Api モジュールでワイヤアダプタを使用するときは、参照をオブジェクトと項目にインポートすることを強くお勧めします。そうすることで、オブジェクトと項目が存在することを検証し、オブジェクトや項目が削除されてしまうことを防止して、名前が変更されたオブジェクトや項目をコンポーネントのソースコードにカスケードできます。また、連動オブジェクトや連動項目が変更セットおよびパッケージに含まれることも確認します。オブジェクトや項目への参照をインポートすると、オブジェクトや項目の名前が変更されても、コードは確実に機能します。

コードの例は lwc-recipes リポジトリを参照してください。名前が wire で始まるコンポーネントを探してください。

Tip

コンポーネントがどのオブジェクトを使用しているかが不明な場合は、インポートした参照ではなく文字列を使用してください。オブジェクトの項目を返すには、getObjectInfo を使用します。lightning/ui*Api モジュールのすべてのワイヤアダプタでは、オブジェクトの CRUD ルール、項目レベルのセキュリティ、および共有が考慮されます。ユーザに項目へのアクセス権がない場合、その項目は応答に含まれません。

現時点では、名前の変更がソースコードに完全にカスケードされるまで約 2 時間掛かります。アプリケーションビルダーで使用されているコンポーネントの meta.xml ファイルで <objects> を使用してオブジェクトやレコードのホームを制約している場合には、このタイミングも重要になります。

Note

オブジェクトや項目の API 参照名にアクセスするには、import ステートメントを使用します。すべてのオブジェクトおよび項目のインポートは、@salesforce/schema 範囲設定されたパッケージに含まれています。

オブジェクトへの参照をインポートするには、次の構文を使用します。

1import objectName from "@salesforce/schema/object";
2import objectName from "@salesforce/schema/namespace__object";
3
4import POSITION_OBJECT from "@salesforce/schema/Position__c";
5import ACCOUNT_OBJECT from "@salesforce/schema/Account";

項目への参照をインポートするには、次の構文を使用します。

1import FIELD_NAME from "@salesforce/schema/object.field";
2
3import POSITION_LEVEL_FIELD from "@salesforce/schema/Position__c.Level__c";
4import ACCOUNT_NAME_FIELD from "@salesforce/schema/Account.Name";

リレーション経由で項目への参照をインポートするには、次の構文を使用します。リレーション項目を使用して親オブジェクト項目にトラバースできます。リレーション項目は 3 つまで指定できるため、結果として 4 つのオブジェクトと項目が参照されます。たとえば、Opportunity.Account.CreatedBy.LastModifiedById は 4 レベルの拡張項目を返します。

1import SPANNING_FIELD_NAME from "@salesforce/schema/OBJECT.RELATIONSHIP.FIELD";
2
3import POSITION_HIRINGMANAGER_NAME_FIELD__c from "@salesforce/schema/Position__c.HiringManager__r.Name__c";
4import ACCOUNT_OWNER_NAME_FIELD from "@salesforce/schema/Account.Owner.Name";

オブジェクトの命名規則は OBJECTNAME_OBJECT です。項目の命名規則は FIELDNAME_FIELD です。これらの命名規則を使用することで、コードを理解しやすくしています。これらはガイドラインであり、ルールではありません。

Tip

次のコードは、Account.Name 項目をインポートして、ワイヤアダプタの設定オブジェクトで使用します。

1import { LightningElement, api, wire } from "lwc";
2import { getRecord } from "lightning/uiRecordApi";
3import ACCOUNT_NAME_FIELD from "@salesforce/schema/Account.Name";
4
5export default class Record extends LightningElement {
6  @api recordId;
7
8  @wire(getRecord, { recordId: "$recordId", fields: [ACCOUNT_NAME_FIELD] })
9  record;
10}

次のコードもほぼ同じですが、文字列を使用して Account.Name 項目を識別しています。このコードには、項目への参照をインポートする場合のような利点はありません。

1import { LightningElement, api, wire } from "lwc";
2import { getRecord } from "lightning/uiRecordApi";
3
4export default class Record extends LightningElement {
5  @api recordId;
6
7  @wire(getRecord, { recordId: "$recordId", fields: ["Account.Name"] })
8  record;
9}

複合項目の参照のインポート 

名前項目、取引先項目、地理位置情報項目は複合項目です。複合項目は、単一の項目、構造化された項目、または個別の構成項目としてアクセスできます。複合項目の値と、構成項目の値は、どちらも Salesforce に保存されている同じデータにマッピングされます。

読み取り操作では、複合項目またはその構成項目への参照をインポートできます。たとえば、読み取り操作では、複合項目 Contact.Name を使用できます。

1import NAME_FIELD from "@salesforce/schema/Contact.Name";

updateRecord(recordInput, clientOptions) などの lightning/ui*Api 関数を使用して複合項目を作成、更新する場合は、構成項目をインポートする必要があります。たとえば、Contact.Name ではなく Contact.FirstNameContact.LastName をインポートします。必須の構成項目をすべて含めてください。たとえば、取引先責任者を作成する場合は LastName 項目は必須です。

1import FIRSTNAME_FIELD from "@salesforce/schema/Contact.FirstName";
2import LASTNAME_FIELD from "@salesforce/schema/Contact.LastName";

複合住所項目は、その構成項目を介してサポートされます。住所項目にアクセスするには、文字列構文でその構成項目を使用します。

1const STREET_FIELD = "Contact.MailingStreet";
2const CITY_FIELD = "Contact.MailingCity";

複合地理位置情報項目は、その構成項目を介してサポートされます。地理位置情報項目にアクセスするには、文字列構文でその構成項目を使用します。

1// User.Place_of_birth__c is a compound custom field of type Geolocation
2const PLACE_OF_BIRTH_LAT_FIELD = "User.Place_of_birth__Latitude__s";
3const PLACE_OF_BIRTH_LON_FIELD = "User.Place_of_birth__Longitude__s";

「Lightning Web コンポーネントを使用した熊追跡アプリケーションの作成」Trailhead プロジェクトでは、複合地理位置情報項目を使用して、緯度と経度のデータを地図マーカーに変換します。

Tip

インポートの制限 

Salesforce ではさまざまなデータ型を表す多くのオブジェクトサフィックスと項目サフィックスがサポートされています。Lightning Web コンポーネントでは、標準オブジェクトへの参照のインポートと、カスタムオブジェクト (__c) への参照のインポートのみがサポートされています。次に例を示します。

1import POSITION_OBJECT from "@salesforce/schema/Position__c";

その他のオブジェクトサフィックスや項目サフィックスへの参照をインポートする場合は、次の回避策を検討します。

個人取引先

__pc 項目は個人取引先を表します。個人取引先では、特定の取引先項目および取引先責任者項目が 1 つのレコードに結合されて、個人に関する情報が保存されます。取引先責任者オブジェクトで作成されるすべてのカスタム項目は、__pc サフィックスを使用することで、取引先オブジェクトの個人取引先で使用できますが、この構文は import ステートメントでは機能しません。

取引先オブジェクトから __pc 項目をインポートするのではなく、取引先責任者オブジェクトからカスタム項目をインポートすると、参照整合性の利点が得られます。

1import PA_CONTACT_CUSTOM_FIELD from "@salesforce/schema/Contact.myCustomField__c";

JavaScript ファイルの後半で、Contact.myCustomField__c を参照する Account.myCustomField__pc 項目に直接アクセスできます。次に例を示します。

1paField = "Account.myCustomField__pc";
外部オブジェクト

__x サフィックスは外部カスタムオブジェクトを表します。外部カスタムオブジェクトはカスタムオブジェクトと似ていますが、Salesforce 組織外に保存されたデータに対応付けられるという点が異なります。

外部のカスタムオブジェクトからデータを取得するには、SOQL クエリでデータを取得する、Apex クラスのメソッドをコールします。

設定オブジェクトプロパティの動的またはリアクティブとしてのマーク 

ワイヤアダプタの設定オブジェクトで、コンポーネントインスタンスのプロパティを参照するには、値にプレフィックスの $ を付けます。$ プレフィックスは、プロパティをクラスのプロパティとして扱って、this.propertyName として評価するようにワイヤサービスに指示します。プロパティはリアクティブです。値が変化すると、新しいデータがプロビジョニングされ、コンポーネントが再表示されます。

設定オブジェクトの最上位の値に $ プレフィックスを使用します。['$accountIds'] のように配列などで $ プレフィックスをネストすると、動的またはリアクティブでないリテラル文字列になります。

次の例の $recordId は、動的およびリアクティブです。

1import { LightningElement, api, wire } from "lwc";
2import { getRecord, getFieldValue } from "lightning/uiRecordApi";
3
4import REVENUE_FIELD from "@salesforce/schema/Account.AnnualRevenue";
5
6const fields = [REVENUE_FIELD];
7
8export default class WireGetValue extends LightningElement {
9  @api recordId;
10
11  @wire(getRecord, { recordId: "$recordId", fields })
12  account;
13
14  get revenue() {
15    return getFieldValue(this.account.data, REVENUE_FIELD);
16  }
17}

前述した例の fields プロパティ値のように $ が付いていない値は静的な値 [AccountNameField] となります。

これらの種類の設定オブジェクトプロパティは、動的およびリアクティブとしてマークできます。

  • Private のプロパティ
  • getter と setter のペアによって定義されるプロパティ
  • @api でデコレートされるプロパティ

@wire でのプロパティのデコレート 

データやエラーをそのまま消費する場合は、プロパティのワイヤリングが便利です。

@wire でデコレートされ、テンプレートで属性として使用されているプロパティの値が変化すると、ワイヤサービスはデータをプロビジョニングして、コンポーネントの再表示をトリガします。プロパティは非公開ですが、リアクティブです。

次のコードは、@wirerecord プロパティに適用しています。

1import { LightningElement, api, wire } from "lwc";
2import { getRecord } from "lightning/uiRecordApi";
3import ACCOUNT_NAME_FIELD from "@salesforce/schema/Account.Name";
4
5export default class Record extends LightningElement {
6  @api recordId;
7
8  @wire(getRecord, { recordId: "$recordId", fields: [ACCOUNT_NAME_FIELD] })
9  record;
10}

コンポーネントを構成してから他のライフサイクルイベントが発生するまでの間に、このプロパティにはデフォルト値が割り当てられます。

デフォルト値は、data プロパティと error プロパティが undefined に設定されたオブジェクトです。

1{ data: undefined, error: undefined }

そのため、テンプレートで使用されている関数や、コンポーネントライフサイクルの一環として使用されている関数など、あらゆる関数でプロパティの値にアクセスできます。

プロパティ (この例では record) に供給されるオブジェクトは、次のようになります。

  • data (任意の型) — アダプタから供給される値。
  • error (エラー) — アダプタがリクエストされたデータを供給できない場合、またはアダプタが見つからない場合はエラーとなります。コミュニティにログインしていない場合、このプロパティは undefined になります。

ワイヤアダプタからデータが供給されると、data プロパティに設定されます (errorundefined のままです)。データの新しいバージョンが利用できるようになると、data が更新されます。

データの取得中などにアダプタでエラーが発生すると、error にエラーオブジェクトが設定されます (dataundefined に設定されます)。

ある @wire 出力を別の @wire 入力として使用できます。たとえば、$record.data.fieldName を別のワイヤアダプタへの入力として使用できます。

@wire での関数のデコレート 

関数のワイヤリングは、新しいデータが提供された場合やエラーが発生した場合にロジックを実行するのに便利です。ワイヤサービスは、ワイヤリングされたプロパティと同じように、error プロパティと data プロパティを持つオブジェクトを関数にプロビジョニングします。

コンポーネントの接続や表示の前後であっても、値が利用できる場合であればいつでも関数を呼び出せます。

1// wireFunction.js
2import { LightningElement, api, track, wire } from "lwc";
3import { getRecord } from "lightning/uiRecordApi";
4
5export default class WireFunction extends LightningElement {
6  @api recordId;
7  @track record;
8  @track error;
9
10  @wire(getRecord, { recordId: "$recordId", fields: ["Account.Name"] })
11  wiredAccount({ error, data }) {
12    if (data) {
13      this.record = data;
14      this.error = undefined;
15    } else if (error) {
16      this.error = error;
17      this.record = undefined;
18    }
19  }
20  get name() {
21    return this.record.fields.Name.value;
22  }
23}
1<!-- wireFunction.html -->
2<template>
3  <lightning-card title="Wire Function" icon-name="standard:contact">
4    <template lwc:if={record}>
5      <div class="slds-m-around_medium">
6        <p>{name}</p>
7      </div>
8    </template>
9    <template lwc:if={error}>
10      <c-error-panel errors={error}></c-error-panel>
11    </template>
12  </lightning-card>
13</template>

関連トピック

The Japanese Summer '24 guide is now live

日本語の Summer '24 ガイドが公開されました! 「Component Reference (コンポーネントリファレンス)」は、以前と同様にコンポーネントライブラリにあります。