如何为具有列表/详细信息视图和分页的应用程序选择 Redux 状态形状? [英] How to choose the Redux state shape for an app with list/detail views and pagination?

查看:13
本文介绍了如何为具有列表/详细信息视图和分页的应用程序选择 Redux 状态形状?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

想象一下,我的数据库中有许多条目(比如用户).我也有两条路线,一条用于列表,另一条用于详细信息(您可以在其中编辑条目).现在我正在为如何处理数据结构而苦苦挣扎.

Imagine I have a number of entries(say, users) in my database. I also have two routes, one for list, other for detail(where you can edit the entry). Now I'm struggling with how to approach the data structure.

我正在考虑两种方法以及两者的结合.

I'm thinking of two approaches and a kinda combination of both.

  • 我导航到/list,我所有的用户都是从api下载的,存储在redux store中,在键users下,我还添加了某种users_offsetusers_limit 仅呈现列表的一部分
  • 然后我导航到 /detail/,并将 currently_selected_user 存储为 val...这意味着我将能够使用这样的内容获取我的用户数据 users.find(res => res.id === current_selected_user)
  • 更新也很简单,因为我只处理一个数据集和指向它的详细信息
  • 添加新用户也很容易,同样只需使用相同的用户列表
  • I navigate to /list, all of my users are downloaded from api a stored in redux store, under the key users, I also add some sort of users_offset and users_limit to render only part of the of the list
  • I then navigate to /detail/<id>, and store currently_selected_user with <id> as the val... which means I will be able to get my user's data with something like this users.find(res => res.id === currently_selected_user)
  • updating will be nice and easy as well, since I'm working with just one data set and detail pointing to it
  • adding a new user also easy, again just working with the same list of users

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

Now the problem I have with this approach is that, when the list of users gets huge(say millions), it might take a while to download. And also, when I navigate directly to /detail/<id>, I won't yet have all of my users downloaded, so to get data for just the one I need, I'm gonna have to first download the whole thing. Millions of users just to edit one.

  • 我导航到 /list,而不是从 api 下载我的所有用户,我只下载其中的几个,具体取决于我的 users_per_pageusers_current_page 将设置为,我可能会将数据存储为 users_currently_visible
  • 然后我导航到 /detail/,将 currently_selected_user 存储为 val...和而不是通过 users_currently_visible 搜索我只是从 api 下载用户的数据..
  • 更新时,我不会以任何方式更新users_currently_visible
  • 我也不会添加
  • I navigate to /list, and instead of downloading all of my users from api, I only download a couple of them, depending on what my users_per_page and users_current_page would be set to, and I'd probably store the data as users_currently_visible
  • I then navigate to /detail/<id>, store currently_selected_user with <id> as the val...and instead of searching through users_currently_visible I simply download user's data from api..
  • on update, I'm not gonna update users_currently_visible in any way
  • nor will I on add

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

What I see as possible problem here is that I'm gonna have to, upon visiting /list, download data from api again, because it might not be in sync with what's in the database, I also might be unnecessarily downloading users data in detail, because they might be incidentally already inside my users_currently_visible

  • 我详细说明,我和分离数据集一样,但不是直接从 api 下载用户的数据,我首先检查:
    • 我有任何users_currently_visible
    • 如果是这样,他们之间是否有与我的 ID 相同的用户?如果两者都为真,则我将其用作我的用户数据,否则我进行 api 调用
    • I detail, I do the same as in Separated data set but instead of directly downloading user's data from api, I first check:
      • do I have any users_currently_visible
      • if so, is there a user with my id between them? if both are true, I then use it as my user data, otherwise I make the api call

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

      This would probably work, but doesn't really feel like it's the proper way. I would also probably still need to download fresh list of users_currently_visible upon visiting /list, because I might have added a new one..

      有没有粉丝最喜欢的方式来做到这一点?...我相信每个 redux 用户都遇到过同样的事情.

      Is there any fan favorite way of doing this?... I'm sure every single one redux user must have encountered the same things.

      谢谢!

      推荐答案

      请咨询来自 Redux 存储库的真实世界"示例.
      它显示了这个问题的解决方案.

      Please consult "real world" example from Redux repo.
      It shows the solution to exactly this problem.

      您的状态形状应如下所示:

      Your state shape should look like this:

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

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

      Note I’m storing entities (ID -> Object maps) and visibleUsers (description of currently visible users with pagination state and IDs) separately.

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

      This seems similar to your "Shared data set" approach. However I don’t think the drawbacks you list are real problems inherent to this approach. Let’s take a look at them.

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

      Now the problem I have with this approach is that when then list of users gets huge(say millions), it might take a while to download

      您无需全部下载!将所有下载的实体合并到 entities 并不意味着您应该查询所有实体.entities 应包含到目前为止已下载的所有实体,而不是世界上的所有实体.相反,您只需根据分页信息下载当前显示的内容.

      You don’t need to download all of them! Merging all downloaded entities to entities doesn’t mean you should query all of them. The entities should contain all entities that have been downloaded so far—not all entities in the world. Instead, you’d only download those you’re currently showing according to the pagination information.

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

      when I navigate directly to /detail/, I wouldn't yet have all of my users downloaded, so to get data for just the one, I'm gonna have to download them all. Millions of users just to edit one.

      不,您只需要其中之一.响应操作将触发,负责entities 的reducer 会将这个单一实体 合并到现有状态中.仅仅因为 state.entities.users 可能包含多个用户并不意味着您需要下载所有用户.将 entities 视为不需要 填充的缓存.

      No, you’d request just one of them. The response action would fire, and reducer responsible for entities would merge this single entity into the existing state. Just because state.entities.users may contain more than one user doesn’t mean you need to download all of them. Think of entities as of a cache that doesn’t have to be filled.

      最后,我将再次引导您查看真实世界"示例 来自 Redux 存储库.它准确地展示了如何为分页信息和实体缓存编写 reducer,以及如何使用 normalizr 以便reducer 可以轻松地以统一的方式从服务器操作中提取信息.

      Finally, I will direct you again to the "real world" example from Redux repo. It shows exactly how to write a reducer for pagination information and entity cache, and how to normalize JSON in your API responses with normalizr so that it’s easy for reducers to extract information from server actions in a uniform way.

      这篇关于如何为具有列表/详细信息视图和分页的应用程序选择 Redux 状态形状?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆