web-dev-qa-db-ja.com

リレーを使用するときにローカル状態を処理する方法は?

私はreact/relayベースのコンテンツ管理システムに取り組んでいます。ユーザーは、サーバーに保存されている記事を作成および変更できます。サーバーに保存する前に記事の変更された状態を処理するのが最善の方法だと思っていました。私はこれを解決するためにいくつかの異なる方法を考えることができます:

1)制御されていない入力

defaultValueを使用して入力要素にデータを入力でき、状態を明示的にどこにも保存できません。 DOMは、変更されたデータのストアとして使用されます。ユーザーが「保存」を押すと、すべてのフィールドを収集し、値を読み取り、ミューテーションを作成します。

プロ:

  • 地方の州の取り扱いはありません

対照:

  • どのフィールドが変更されたかを実際に知ることはできず、ミューテーションを介してすべてのデータを送信する必要があります。または、差分を作成するためにいくつかの追加のロジックが必要になります
  • 状態変化に応じてビューの他の部分を更新することはできません

2)ローカル状態でコピー:

変更された記事をReactコンポーネントのローカル状態に保ち、制御された入力フィールドを使用して同期を維持することができます。

プロ:

  • ローカル状態はフィールドを変更することしかできなかったので、差分は簡単です
  • UIの他の部分は、ローカル状態の変更に応答できます

対照:

  • ビュー内のデータがリレーから直接送信されていないため、これは一種のアンチパターンのようです。ローカル状態とリレー小道具の間の同期はバグの原因となる可能性があります

)サーバーは新しいローカルです:

行われるすべての変更に対してミューテーションを作成するだけです。楽観的な更新を使用すると、これも優れたUXを提供するはずです。

プロ:

  • リレーはデータの唯一の真実の源です
  • 状態はサーバー側に保存されるため、ユーザーが誤ってブラウザを閉じた場合のバックアップがあります

対照:

  • これには、ユーザーがドラフトを破棄したい場合などを処理するために、サーバー側でより複雑な実装が必要になります。
  • 多くの突然変異が引き起こされた

これらは私が考えることができるこれを解決するための3つの方法ですが、おそらくこれを解決するためのさらに良い方法があります。

Relayでローカル状態を処理する方法について多くの議論が行われていることを確認しました。また、Relayの将来のバージョンで組み込みのソリューションが提供される可能性がありますが、現在のバージョンのRelayで機能するソリューションが必要です。リレー。

35
danielbuechele

簡単な答え:状況によって異なりますが、私は#2ソリューションを好みます

1.なぜ私は#2を好むのか

ソリューション#2はソリューション#1の高度なバージョンであるため、#1に合格します。しかし、もちろんその1つは事実であり、ほとんどの古いサイトはそうしています。

ソリューション#3はサーバーをビジー状態に保ちます。これにより、サーバーのコストが上昇するか、ビジネスの規模が拡大したときにユーザーエクスペリエンスが低下するため、#3に合格します。しかし、内部システムまたはより少ないユーザーによって使用されることを意図したいくつかのビジネスとして、#3は良い選択になります。

ユーザーが誤ってブラウザを閉じた場合

解決策#2でも、間隔を使用してコンテンツをサーバーに同期できます。確かにauto save in xx seconds 何度も。または、localstorageを使用することもできます。クロスコンピューターは保存されませんが、同期ラグがゼロのすべての履歴であっても、変更のすべてのビットが保存されます。

2.アンチパターンではありません

ローカル状態とリレー小道具の間の同期はバグの原因となる可能性があります

他の誰かが同時に記事を変更した場合、これは#2だけで起こるのではないと言うべきです

#1の場合、変更は上書きされ、変更が行われた場所の手がかりを見つけることはできません。

#3の場合、コンテンツは常に変化していますが、それでも作業できますか?

したがって、そのような場合は、バージョン管理ロジックを追加する必要がありますか?そのような場合がない場合、あなたの地域の州は唯一の正しい情報源です。

1
Josh Lin

私が間違っている場合は訂正してくださいが、2つの問題を混同していると思います:ローカル状態をどこに保存するかという問題について話し合っていますが、実際には2人の人(たとえば別の人)によって行われる変更の競合の問題に関心があります人は、現在のユーザーが編集しているのと同じ記事を編集します)。これは、アプリがサーバーから更新をアクティブにフェッチしている場合にのみ発生するリレー小道具の変更について話しているためだと思います。そのような更新をフェッチする必要があります。

ビュー内のデータはリレーから直接取得されていないため、これは一種のアンチパターンのようです。ローカル状態とリレー小道具の間の同期はバグの原因となる可能性があります

リレーアプリケーションは、そうしない限り、サーバーと常に同期しているわけではありません。リレークエリ、およびコンポーネントに渡される小道具は常に更新されていません。競合の可能性がある場合は、その問題を解決する必要があります。これはリレーの問題ではなく、ローカル状態を格納する場所ではその問題を解決できません。

競合を処理する最も簡単な方法は次のとおりです。

  • ローカル状態にはオプション#2を使用します
  • 編集のために記事をダウンロードするときにフェッチする自動インクリメントバージョン#をすべての記事に与えます
  • 動作しているベースバージョン#を指定するには、記事編集の変更が必要です。サーバーは、現在のバージョンではないベースを持つミューテーションを拒否する必要があります。競合する変更があり、最新バージョンで動作しておらず、保存を許可できないことをユーザーに伝えます。

FWIW私は複雑なリレーアプリケーションに取り組んできましたが、常に#2に頼ってきました。ローカルReact状態は素晴らしく、制御された入力は素晴らしく、アンチパターン、リレー、その他ではありません。

0
Alan