如何在 redux 中构建我的商店以实现主从视图?

Jon*_*ter 5 javascript redux ngrx

我正在使用 Redux 构建电子邮件收件箱。屏幕的一半有电子邮件主题列表,您可以单击其中一个以在屏幕的另一半上查看完整的电子邮件内容。大多数开发人员将其称为“主从”类型的应用程序。

显示在“主”列表中的电子邮件(它是我的应用程序中名为 的类SimpleEmail)如下所示。该模型已缩小,以减少获取可能包含 100 多封电子邮件的列表时传输的数据量。

{
  from: "hello@site.com",
  subject: "Hello, Jon",
  id: "abc123"
}
Run Code Online (Sandbox Code Playgroud)

“详细信息”列表中的电子邮件(名为 的类EmailDetails)具有更复杂且形状不同的模型。

{
  id: "abc123"
  headers: {
    from: "hello@site.com",
    subject: "Hello, Jon",
    to: [],
    bcc: null,
    cc: null,
    replyTo: // and about 10 more fields
  },
 bodyHtml: "This is some text",
  attachments: [],
  receivedAt: null,
  // and about 10 other fields
}
Run Code Online (Sandbox Code Playgroud)

我应该如何在 redux 中塑造我的应用程序状态来处理正在使用的这两种不同的模型?我最初的想法是执行以下操作:

{
   emailMaster: {
     entitiesById: {},  // a Map of emails keyed by ID
     ids: [],
     selectedId: null
     isFetching: false,
     isError: false
   },
   emailDetails: {
    selectedEntity: {},   // A single email object
    isFetching: false,
    isError: false
   }
}
Run Code Online (Sandbox Code Playgroud)

我已经发现我的设计存在一些问题:

  • 数据未标准化,因此存在重复数据。这违反了 redux 的一个主要设计原则。
  • 如果用户更新电子邮件(例如将其标记为未读),我将必须检查该电子邮件是否已加载到“详细信息”视图中,并更新第二个模型。这看起来像是代码味道。
  • 没有选择电子邮件 ID 的单一事实来源。如果存在竞争条件(也许用户在屏幕上单击得非常快)并且emailMaster.selectedId与 的值不同怎么办emailDetails.selectedEntity.id?再说一次,这看起来像是代码味道。

显然感觉有些不对劲。有没有更好的方法来设计我的应用程序状态的形状?