web-dev-qa-db-ja.com

リスト/詳細ビューとページネーションを備えたアプリのRedux状態形状を選択する方法は?

データベースに多数のエントリ(ユーザーなど)があるとします。また、2つのルートがあります。1つはリスト用、もう1つは詳細用です(ここでエントリを編集できます)。現在、データ構造にアプローチする方法に苦労しています。

私は2つのアプローチと両方のちょっとした組み合わせを考えています。

共有データセット

  • /listに移動し、すべてのユーザーがusersの下にあるreduxストアに保存されているAPIからダウンロードされます。また、users_offsetusers_limitを追加しますリストの一部のみをレンダリングする
  • 次に/detail/<id>に移動し、currently_selected_userをvalとして<id>に格納します...これは、このusers.find(res => res.id === currently_selected_user)のようなものでユーザーのデータを取得できることを意味します
  • 更新も素敵で簡単になります。1つのデータセットとそれを指す詳細だけを扱っているからです。
  • 新しいユーザーの追加も簡単で、同じユーザーのリストで作業するだけです

さて、このアプローチに伴う問題は、ユーザーのリストが膨大になると(数百万人など)、ダウンロードに時間がかかる可能性があることです。また、/detail/<id>に直接移動すると、まだすべてのユーザーがダウンロードされていないため、必要なユーザーだけのデータを取得するには、まずすべてをダウンロードする必要があります。 1つを編集するだけで何百万人ものユーザー。

分離されたデータセット

  • /listに移動し、APIからすべてのユーザーをダウンロードする代わりに、users_per_pageおよびusers_current_pageの設定に応じて、そのうちの2、3のみをダウンロードします。おそらくデータをusers_currently_visibleとして保存します
  • 次に、/detail/<id>に移動し、currently_selected_userをvalとして<id>に格納し、users_currently_visibleを検索する代わりに、単にAPIからユーザーのデータをダウンロードします。
  • 更新時に、users_currently_visibleを更新するつもりはありません
  • また、私は追加しません

ここで考えられる問題は、/listにアクセスしたときに、再度APIからデータをダウンロードする必要があることです。データベース内のデータと同期していない可能性があり、不必要にユーザーをダウンロードしている可能性もありますusers_currently_visibleに偶然既に含まれている可能性があるため、データの詳細

ある種のフランケンシュタインyシェナンガン

  • 詳細は、Separated data setと同じですが、apiからユーザーのデータを直接ダウンロードする代わりに、最初にチェックします:
    • users_currently_visibleはありますか
    • もしそうなら、それらの間に私のIDを持つユーザーがいますか?両方とも当てはまる場合は、ユーザーデータとして使用します。それ以外の場合は、API呼び出しを行います
  • 更新時にも同じことが起こります。ユーザーがusers_currently_visibleの間に存在するかどうかを確認します。存在する場合は、リストも更新します。

これはおそらく機能しますが、実際には適切な方法であるとは感じません。また、users_currently_visibleにアクセスしたときに/listの新しいリストをダウンロードする必要があります。新しいリストを追加した可能性があるためです。

これを行うためのファンのお気に入りの方法はありますか...

ありがとう!

59
fxck

Reduxリポジトリの 「実世界」の例 を参照してください。
これはまさにこの問題の解決策を示しています。

状態の形状は次のようになります。

{
  entities: {
    users: {
      1: { id: 1, name: 'Dan' },
      42: { id: 42, name: 'Mary' }
    }
  },
  visibleUsers: {
    ids: [1, 42],
    isFetching: false,
    offset: 0
  }
}

entities(ID->オブジェクトマップ)とvisibleUsers(ページネーション状態とIDを持つ現在表示されているユーザーの説明)を別々に保存しています。

これは、「共有データセット」アプローチに似ています。しかし、あなたが挙げた欠点は、このアプローチに固有の本当の問題だとは思いません。それらを見てみましょう。

このアプローチで問題になっているのは、ユーザーのリストが膨大になると(数百万など)、ダウンロードに時間がかかる可能性があることです。

すべてをダウンロードする必要はありません!ダウンロードしたすべてのエンティティをentitiesにマージしても、それらすべてをクエリする必要はありません。 entitiesには、これまでにダウンロードされたすべてのエンティティ /が含まれている必要があります。世界のすべてのエンティティではありません。代わりに、ページネーション情報に従って現在表示しているもののみをダウンロードします。

/ detail /に直接移動すると、まだすべてのユーザーがダウンロードされていないため、1人だけのデータを取得するには、すべてをダウンロードする必要があります。 1つを編集するだけで何百万人ものユーザー。

いいえ、そのうちの1つだけをリクエストします。応答アクションが起動し、entitiesを担当するリデューサーがこの単一のエンティティを既存の状態にマージします。理由はstate.entities.usersに複数のユーザーが含まれている可能性があるため、すべてのユーザーをダウンロードする必要はありません。 entitiesは、haveが満たされないキャッシュと考えてください。


最後に、Reduxリポジトリの 「実世界」の例 に再度案内します。ページネーション情報とエンティティキャッシュ用のレデューサーの正確な記述方法、および normalizrでAPI応答のJSONを正規化する方法 により、レデューサーがサーバーアクションから情報を簡単に抽出できるようになります均一な方法で。

75
Dan Abramov