項目、オブジェクト、配列のリアクティビティ

項目の値が変更され、その項目がテンプレートで使用されているか、テンプレートで使用されているプロパティの getter で使用されている場合、コンポーネントは再表示され、新しい値を表示します。項目にオブジェクトまたは配列が割り当てられている場合、フレームワークによりオブジェクトまたは配列内部の変更 (新しい値を割り当てた場合など) が監視されます。

コンポーネントが再表示されると、テンプレートで使用されている式が再評価され、renderedCallback() ライフサイクルフックが実行されます。

姓または名の項目に値を入力すると、コンポーネントは名前を大文字に変換して表示します。

名と姓の入力項目。入力された名前は大文字に変換されます。

コンポーネントのクラスで firstName 項目と lastName 項目を定義しています。これらは、テンプレートで使用されているプロパティ (uppercasedFullName) の getter で使用されているため、値が変更されるとコンポーネントが再表示されます。

項目はリアクティブです。実行時にオブジェクトに追加されるプロパティである Expando プロパティは、リアクティブではありません。

lwc-recipes リポジトリの helloExpressions コンポーネントを参照してください。

項目はリアクティブですが、LWC エンジンでは項目値の変更を浅い方法で追跡します。新しい値が項目に追加されると、=== を使用して値の ID が比較され、変更が検出されます。このアプローチは、数値や Boolean などのプリミティブ型に適しています。

オブジェクトや配列などの複雑なデータ型を操作する場合、変更を検出するには新しいオブジェクトを作成して項目に割り当てる必要があります。

複雑なオブジェクトを操作するときにこのような問題を回避するには、@track デコレーターを使用して項目値に対する変異を深く追跡します。

オブジェクトのプロパティまたは配列の要素の変更を監視するには、項目を @track でデコレートします。

項目が @track でデコレートされている場合、Lightning Web コンポーネントでは次の内部値に対する変更を追跡します。

  • {} で作成されたプレーンオブジェクト
  • [] で作成された配列

フレームワークでは、ネストされたオブジェクト、ネストされた配列、オブジェクトと配列の混合を含め、プレーンオブジェクトおよび配列に対して行われた変異を再帰的な方法で監視します。循環参照も処理されます。

ただし、フレームワークでは Object から継承するオブジェクト、クラスインスタンス、DateSetMap などの複雑なオブジェクトに対する変異を監視しません。

@track デコレーター

オブジェクトのプロパティの変更を監視するようにフレームワークに指示するには、項目を @track でデコレートします。

上記のとおり、@track を使用しない場合、フレームワークは、項目に新しい値を割り当てる変更を監視します。新しい値と以前の値が === ではない場合、コンポーネントは再表示されます。

たとえば、コードを少し変更して、firstNamelastName の 2 つのプロパティを持つオブジェクトが含まれる fullName 項目を宣言してみましょう。フレームワークは、fullName に新しい値を割り当てる変更を監視します。

このコードは、fullName 項目に新しい値を割り当てるため、コンポーネントが再表示されます。

ただし、オブジェクトのプロパティの 1 つに新しい値を割り当てた場合、コンポーネントは再表示されません。プロパティは監視されていないためです。

フレームワークは、fullName 項目に新しい値を割り当てる変更を監視します。このコードではこれを行いません。代わりに、fullName オブジェクトの firstName プロパティに新しい値を割り当てます。

オブジェクトのプロパティの変更を監視するようにフレームワークに指示するには、fullName 項目を @track でデコレートします。これで、どちらかのプロパティを変更した場合、コンポーネントは再表示されます。

プロパティにオブジェクトが含まれる場合、オブジェクトのプロパティに対する変更を追跡するには、プロパティに @track のアノテーションを付けます。理解しやすくするため、例を少し変更してみましょう。この例では firstNamelastName をプリミティブ値である空白の文字列に初期化し、これらが変更されたときにコンポーネントが再表示されるようにしています。

オブジェクトに @track のアノテーションが付加されているとしても、コンポーネントは前の表示サイクル中にアクセスしたプロパティが更新されている場合のみ再表示されます。これにより、コンポーネントが過度に再表示されるのを防ぎます。

次の追跡されているオブジェクトと、オブジェクトのプロパティを出力する getter を検討します。

最初の表示サイクル中に、フレームワークでは obj.value1 がアクセスされたことを記録します。obj に対する変異のうち、value1 に影響しないものはすべて無視されます。これは、表示されるコンテンツに影響しないためです。そのため、value1 に対する変更を行うと再表示がトリガーされますが、obj に新しいプロパティを追加するか value2 に対する変更を行っても再表示はトリガーされません。

新しいプロパティを追加するときにコンポーネントを再表示するには、両方の値を使用してオブジェクトを新しいオブジェクトに割り当てます。

@track のもう 1 つの使用事例は、配列の要素の変更を監視するようフレームワークに指示することです。

@track を使用しない場合、フレームワークは、項目に新しい値を割り当てる変更を監視します。

arr に新しい値を割り当てると、コンポーネントは再表示されます。

ただし、配列の要素を更新または追加した場合は、コンポーネントは再表示されません。

配列の要素の変更を監視するようにフレームワークに指示するには、arr 項目を @track でデコレートします。さらに、配列の要素の更新についてフレームワークでは自動的に配列を文字列に変換しません。更新された文字列を返すには、getter を使用し、join() を使用して配列の要素を文字列に変換します。

Date 型の項目 x を持つコンポーネントを見てみましょう。テンプレートには、x の内部状態を変更するボタンがいくつかあります。次の例で強調しているのは、new Date() でオブジェクトが作成されることです。これはプレーン JavaScript オブジェクトではないため、コードで @track を使用していても、内部状態の変異は LWC エンジンによって監視されません。

上の例と同様に、テンプレートには、x の内部状態を変更するボタンがいくつかあります。

[Init] ボタンをクリックすると、変更が検出されて、テンプレートが再表示されます。Lightning Web コンポーネントは、x が新しい Date オブジェクトを指していることを追跡しています。一方、[Update] をクリックしても、テンプレートは再表示されません。Lightning Web コンポーネントは Date オブジェクトの値への変更を追跡していないためです。

値が変更されたときにテンプレートが再表示されるようにするには、既存の日付をコピーしてその値を更新します。

プロパティを追跡できない値に設定すると、警告がログに記録されます。変更に対してコンポーネントが再表示されない状況をデバッグする場合は、ブラウザーコンソールを確認してください。たとえば、ブラウザーコンソールには、次のような役に立つ警告が出力されています。

Property "x" of [object:vm TrackDate] is set to a non-trackable object, which means changes into that object cannot be observed.

関連トピック