画面フローのリアクティビティに関するベストプラクティス

Lightning Web コンポーネントがフローランタイムエンジンに適切に統合され、画面フローの反応が期待通りに動作することを確認します。

以下のセクションでは、画面フローでリアクティビティを使用した次のような状態管理について説明します。

  • LWC と Aura の状態管理の違い
  • 新しい LWC フローランタイムでの状態管理の仕組み
  • 画面フロー用の LWC を作成する際に従うべき状態管理とイベントのベストプラクティス

Aura コンポーネントと LWC の状態管理は、異なる原則に従っています。Aura コンポーネントでは、<aura:attributes /> は、それらが属するコンポーネント (外部コンポーネントを含む) によって表示および変更されます。LWC では内部と外部の状態を明確に分離するように設計されています。@api で宣言された変数は、LWC の親によってのみ変更されることが意図されています。@api アノテーションのない変数と @track アノテーションのある変数は内部状態とみなされ、これらを定義している LWC 内で変更できます。

フローランタイムは、LWC の状態管理の設計原則に従ったものです。これは、表示される LWC コンポーネントが自身の @api 属性を変更しない場合に最適に機能します。代わりに、コンポーネントは FlowAttributeChangeEvent を起動することによって変更を要求します。これはいくつかの理由から不可欠です。

  • 親が @api プロパティを制御できるコンポーネントは、コンポーネント自身の内部ビジネスロジックではなく、アプリケーションから状態を制御できるため、より簡単に再利用できます。
  • 属性変更イベントを起動することで、フローランタイムはコンポーネントの状態を正確に把握できます。フローランタイムは、リアクティビティの必須要素である条件項目の可視性など、コンポーネント間のインタラクションを制御できます。

LWC リンタールールの使用は、コンポーネントが @api プロパティを変更しないように指定できる優れた方法です。開発環境で LWC のリンタールールを使用するリンターを設定し、特にこの設定が強制されるように指定します。

フローランタイムのバージョン間で一貫した動作を維持するため、ユーザーが [次へ] ボタンまたは [完了] ボタンをクリックすると、フローランタイムは、次の画面に移動するかフローを終了する前に、各カスタム LWC コンポーネントの @api 属性の現在の状態を抽出して値を収集します。このメカニズムにより、規定されている設計パターンに準拠していないコンポーネントが、最新のフローランタイムバージョンでも引き続き動作します。この動作には依存しないことを強く推奨します。

次に、LWC の @api プロパティを更新する代わりに FlowAttributeChangeEvent を実行する、単純なテキスト入力コンポーネントの例を示します。

次の例は非推奨です。

FlowAttributeChangeEvent イベントにより、LWC では現在の状態をランタイムに通知できます。これは、フローランタイムの状態管理メカニズムに含まれる機能です。このイベントは、ユーザーとのインタラクションで、@api プロパティの更新を必要とする変更が行われるたびに起動するように意図されています。

lightning/flowSupport モジュールから FlowAttributeChangeEvent をインポートします。

次に、イベントのインスタンスを作成できます。

FlowAttributeChangeEvent には 2 つの引数が含まれています。

  • apiParameterName — 変更する API プロパティの名前。
  • updatedValue — フロー属性の更新された値。

JavaScript および .js-meta.xml ファイルに表示される API プロパティと一致する文字列を apiParameterName に渡します。

たとえば、exampleApiParameterName が次の 3 か所のすべてでどのように一貫しているかを確認してください。

  • LWC の .js-meta.xml ファイルで属性を宣言します。

  • LWC の .js ファイルで API プロパティを宣言します。

  • FlowAttributeChangeEvent インスタンスを作成します。

.js-meta.xml ファイル内で宣言されたデータ型と一致するように updatedValue を渡します。

  • プロパティをレコードとして宣言します。

  • プロパティを文字列として宣言します。

  • プロパティを数値として宣言します。

  • プロパティを Boolean として宣言します。

FlowAttributeChangeEvent インスタンスを作成したら、this.dispatchEvent(eventToFire) メソッドを使用してイベントを起動できます。

これらの FlowAttributeChangeEvent の例に従って、問題のある使用方法を避け、フローバージョンのアップグレード後に予期しない動作が発生する可能性を低減してください。次のベストプラクティスにより、コンポーネントをより簡単に管理できるようになります。

  • イベントの起動は、イベントハンドラー内、またはイベントハンドラー内から呼び出されるメソッド内で実行します。
  • イベントの値パラメーターを次のデータ型に制限します: 文字列、数値、Boolean 値、JSON (レコードタイプの場合)。
  • イベントの値パラメーターの Flow データ型を LWC の @api プロパティのデータ型と一致させます。
  • 必要に応じて get/set パターンを使用して、@api プロパティの変更に反応するように設定します。

次の例では、getter と setter を使用して @api プロパティの更新を数える方法と、属性の変更イベントを起動する前にカウンターの値を増やす方法を示します。どちらのパターンも有効ですが、得られる結果は若干異なります。

この場合、ユーザーがテキスト入力に変更を入力するたび、および textValue プロパティが変更されたとフローランタイムで判定されるたびに、this.changeCounter が増分されます。この方法では、コンポーネントの初期化と、リアクティビティによるコンポーネント間のインタラクションが考慮されます。中間変数を使用して、set メソッドからの更新を表示します。この例では、textValueToRender がこの役割を果たします。

次のコード例では、属性変更イベントを起動する前にカウンターを増分します。このシナリオでは、get/set パターンを使用しません。

この場合、ユーザーがテキスト入力に変更を入力するたびに this.changeCounter が増分されます。リアクティビティによってこの項目の値が変化しても、カウンターは更新されません。

アノテーションのないプロパティまたは @track プロパティを使用して、変更可能なローカルコンポーネントの状態を管理します。

次の例は、ユーザーに入力テキストボックスといくつかの色見本を表示するカラーピッカーを示しています。カラーピッカーコンポーネントはフローに color を返すので、color にのみ @api アノテーションが必要です。selectedSwatchIdinputValue メンバーは内部のみで、デコレーターは必要ありません。

get メソッドを使用して複数の @api プロパティを結合し、ビューの派生変数を作成します。

前の例よりも複雑なシナリオなどで、すべての @api プロパティの set メソッドに、内部コンポーネントの状態管理に必要な派生メンバー変数に寄与する同じロジックを適用します。このロジックによって、どの寄与属性に加えられた変更も、設定された属性の順序に関係なく、値が正しくレンダリングされます。

@api プロパティは変更しないでください。代わりに、FlowAttributeChangeEvents を起動します。

作成後に FlowAttributeChangeEvent パラメーターを変更しないでください。デフォルトで FlowAttributeChangeEvent インスタンスは composed と bubble が有効になっています。

競合状態が発生する可能性があるため、FlowAttributeChangeEventsFlowNavigationXxx イベントを同時に起動しないでください。ナビゲーションプロセスが開始されるまでに、Lightning Web コンポーネントが更新された値を表示する時間が確保されるわけではありません。

フローコンポーネントの_派生_属性とは、同じコンポーネントの他の属性によって値が決定される属性を意味します。値は、他の 1 つ以上の属性に関連付けられる場合があります。たとえば、データテーブルコンポーネントの firstSelectedRow パラメーターは、selectedRows 属性の値によって値が決まるため、派生属性です。firstSelectedRow パラメーターの具体的な値は、selectedRows 属性の最初の値です。

派生属性を含むフロー画面コンポーネントを作成する場合は、コンポーネントがリアクティビティフレームワークで適切に機能するように、ここで説明するベストプラクティスに従ってください。これらのベストプラクティスにより、以下のような問題を回避することができます。

リアクティビティの連鎖は、あるコンポーネントの属性が変更されたときに、他のコンポーネントの属性が連鎖的に変更されることを意味します。たとえば、ユーザーがデータテーブルコンポーネントの行を選択すると、そのコンポーネントの firstSelectedRow 属性の値が変更され、その結果として名前コンポーネントの firstName 属性が変更されます。そして、名前コンポーネントが変更されたことで、テキストコンポーネントの value 属性が変更されます。

システム管理者が画面を設定するときには、ユーザーが一度画面を離れてから [前へ] または [次へ] ボタンで元の画面に戻ったときに、離れる前にユーザーが指定していた値をフローで保持するかどうかを選択します。

派生属性がリアクティブコンポーネントを含むフロー画面で想定どおりに動作することを保証するためには、以下のガイドラインに従ってください。

  1. 変更を促進する属性の set メソッドの派生属性に対して FlowAttributeChangeEvent イベントを起動します。また、コンポーネントの connectedCallback メソッドの派生属性に対しても FlowAttributeChangeEvent イベントを起動します。例:

  2. connectedCallback メソッドでは FlowAttributeChangeEvent イベントを省略しないでくださいFlowAttributeChangeEvent イベントは 2 か所に含める必要があります。変更を促進する属性の set メソッドでフローが FlowAttributeChangeEvent を実行すると、コンポーネントが DOM 内に存在しないため、イベントは基本的にどこにも行きません。イベントを connectedCallback メソッドに追加すれば、フローがコンポーネントを DOM に追加した時点で、フローランタイムがイベントを消費できます。

  3. set メソッドでは FlowAttributeChangeEvent イベントを省略しないでください。 変更を促進する属性の set メソッドで FlowAttributeChangeEvent を起動することで、変更を促進する属性と派生属性の両方に変更が適用されます。その結果、カスタムコンポーネントを含むリアクティビティチェーンの連鎖が適切に機能します。

  4. Promise.resolve().then(...) を使用して set メソッドでの FlowAttributeChangeEvent の起動を遅延させることで connectedCallback メソッドを省略しないでくださいFlowAttributeChangeEvent を遅延させることで、フローが最初に set メソッドをコールした時点でコンポーネントが DOM 内に存在することが保証されます。ただし、この遅延は、フローが画面を初期化した後でコンポーネントがイベントを起動することも意味します。その結果、フローのランタイムは常に保持されている値を上書きし、再訪問時の値の保持に関する設定が上書きされます。

FlowAttributeChangeEvent に加えて、Lightning Web コンポーネントは、画面間の移動、フローの一時停止または終了のために、ナビゲーションイベントを起動できます。ナビゲーションイベントを使用するには、次の関数を lightning/flowSupport からインポートします。

  • FlowNavigationNextEvent
  • FlowNavigationBackEvent
  • FlowNavigationPauseEvent
  • FlowNavigationFinishEvent

次のスニペットは、ナビゲーションイベントをインポートして起動する方法を示しています。この例では FlowNavigationNextEvent を使用していますが、使用可能なナビゲーション対象のそれぞれにも同じ構造が当てはまります。

ナビゲーションイベントを使用すると、Lightning Web コンポーネントに追加の制御メカニズムを含めることができます。エンドユーザーの操作に反応するときにナビゲーションイベントが起動されます。ナビゲーションイベントを使用する場合は、次のガイドラインを参照してください。

  • イベントハンドラー (またはイベントハンドラーが呼び出すメソッド) でナビゲーションイベントを起動します。
  • ユーザーエクスペリエンスが低下するため、イベントハンドラーの外部でナビゲーションイベントを起動しないでください。
  • renderedCallbackconnectedCallback などのライフサイクルハンドラーでナビゲーションイベントを起動しないでください。
  • 画面をスキップするロジックは、画面のライフサイクルではなく、フロー決定ノードに配置します。
  • ダミー画面でナビゲーションを実行しないでください。フローのパフォーマンスが低下する可能性があります。
  • フロー決定ノードでデータがまだ利用できないために、画面の初期化フェーズ内でナビゲーションを実行する必要があるシナリオが発生した場合は、Idea Exchange にアップグレードの要求を投稿してください。