如何为具有列表/详细信息视图和分页的应用程序选择Redux状态形状?

fxc*_*xck 59 javascript redux ngrx

想象一下,我的数据库中有很多条目(比如用户).我还有两个路由,一个用于列表,另一个用于详细信息(您可以在其中编辑条目).现在我正在努力解决如何处理数据结构问题.

我正在考虑两种方法和两者的有点组合.

共享数据集

  • 我导航到/list,我的所有用户都是从存储在redux存储中的api下载的,在键下users,我还添加了一些 users_offset并且users_limit只渲染部分列表
  • 然后我浏览到/detail/<id>,并存储currently_selected_user<id>作为VAL ...这意味着我将能够与这样的事情让我的用户的数据users.find(res => res.id === currently_selected_user)
  • 更新也很简单,因为我只使用一个数据集和指向它的细节
  • 添加新用户也很简单,再次使用相同的用户列表

现在我用这种方法遇到的问题是,当用户列表变得庞大(比如数百万)时,下载可能需要一段时间.而且,当我直接导航时/detail/<id>,我还没有下载所有用户,所以为了获得我需要的数据,我将不得不先下载整个内容.数百万用户只需编辑一个.

分离的数据集

  • 我导航到/list,而不是从api下载我的所有用户,我只下载了几个,取决于我users_per_pageusers_current_page将要设置的,我可能会将数据存储为users_currently_visible
  • 然后我浏览到/detail/<id>,存储currently_selected_user<id>作为VAL ...和,而不是搜索通过users_currently_visible我只是从API下载用户的数据..
  • 在更新时,我不会users_currently_visible以任何方式更新
  • 我也不会补充

我认为这里可能存在的问题是,在访问时我将不得不/list再次从api下载数据,因为它可能与数据库中的内容不同步,我也可能不必要地详细下载用户数据,因为他们可能偶然已经在我的内心users_currently_visible

某种frankenstein-y shenanigans

  • 我详细说明,我和分离数据集一样,但不是直接从api下载用户数据,我首先检查:
    • 我有没有? users_currently_visible
    • 如果是这样,是否有一个用户在我们之间有我的身份?如果两者都是真的,那么我将其用作我的用户数据,否则我进行api调用
  • 同样在更新时发生,我检查我的用户是否存在,users_currently_visible如果是,我也更新该列表,如果不是我什么都不做

这可能会奏效,但并不觉得这是正确的方法.我可能还需要下载users_currently_visible访问时的新清单/list,因为我可能添加了一个新的...

有没有粉丝喜欢的方式这样做?...我敢肯定每一个redux用户都必须遇到同样的事情.

谢谢!

Dan*_*mov 77

请参考Redux repo的"真实世界"示例.
它显示了解决这个问题的方法.

您的状态应如下所示:

{
  entities: {
    users: {
      1: { id: 1, name: 'Dan' },
      42: { id: 42, name: 'Mary' }
    }
  },
  visibleUsers: {
    ids: [1, 42],
    isFetching: false,
    offset: 0
  }
}
Run Code Online (Sandbox Code Playgroud)

注意我分别存储entities(ID - >对象映射)和visibleUsers(具有分页状态和ID的当前可见用户的描述).

这似乎与您的"共享数据集"方法类似.但是我不认为你列出的缺点是这种方法固有的真正问题.我们来看看他们.

现在我用这种方法遇到的问题是,当用户列表变得庞大(比如数百万)时,下载可能需要一段时间

你不需要下载所有这些!合并所有下载的实体entities并不意味着您应该查询所有这些实体.本entities应包含已下载的所有实体迄今世界-不是所有的实体.相反,您只能根据分页信息下载您当前正在显示的内容.

当我直接导航到/ detail /时,我还没有下载所有用户,所以为了获得数据,我将不得不全部下载.数百万用户只需编辑一个.

不,你只要求其中一个.响应操作将触发,而负责的reducer entities将此单个实体合并到现有状态.仅仅因为state.entities.users可能包含多个用户并不意味着您需要下载所有这些用户.想想entities为不高速缓存中被填补.


最后,我将再次引导您进入Redux repo 的"真实世界"示例.它准确显示了如何为分页信息和实体缓存编写reducer,以及如何在API响应中规范化JSON,normalizr以便reducers可以轻松地以统一的方式从服务器操作中提取信息.

  • 如果您的"主"实体具有与您的"细节"实体不同(更小,更不详细)的模型,那么这应该如何工作?在这种情况下,您别无选择,只能为"master"和"details"使用不同的状态片段. (8认同)
  • 你不能.如果您的应用程序打算在没有关闭标签的情况下使用数天,则此方法对您不起作用,并且您可能会通过Relay之类的方式获得更好的服务.或者你可以在这种方法的基础上实现自己的"垃圾收集".或者只是偶尔刷新页面:-). (3认同)
  • @JonGunter一直在考虑相同...目前我的应用程序从`entities.user [id]`获取缓存用户,并使用它来乐观地填充详细信息页面,同时它在后台执行请求以获取所有详细信息.所以`entities.user`包含一个混合包.某些用户只有一些字段,其他用户拥有所有字段(一旦获取了详细信息).这样做的好处是,您可以很快看到已经提取的任何用户的详细信息页面中填写的一些详细信息.详细信息页面*始终*执行获取请求,因此实体与数据库保持同步. (3认同)
  • 更新了"真实世界"示例的链接:https://github.com/reactjs/redux/tree/master/examples/real-world (2认同)