首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何将一对多的字段作为redux-orm中的数组

如何将一对多的字段作为redux-orm中的数组
EN

Stack Overflow用户
提问于 2017-12-20 19:22:46
回答 1查看 937关注 0票数 1

对于使用redux-orm的聊天应用程序,我有以下模型。每个Conversation包含许多Messages,但一条消息只能属于单个Conversation

代码语言:javascript
复制
export class Message extends Model {
  static modelName = 'Message';
  static fields = {
    id: attr(),
    text: attr(),
    created: attr(),
    from: fk('User'),
    conversation: fk('Conversation', 'messages')
  };
}

export class Conversation extends Model {
  static modelName = 'Conversation';
  static fields =  {
    id: attr(),
    created: attr(),
  };
}

我使用下面的选择器来获取与他们各自的消息的对话列表。

代码语言:javascript
复制
export const getConversations = createSelector(
  getOrm,
  createOrmSelector(orm, session =>  {
    return session.Conversation
      .all()
      .toModelArray()
  })
);

问题出在哪里?每个Conversation实例的Conversation属性是QuerySet,而不是Array,这使得传递ti组件时很难处理。

以下是我尝试过的解决方案:

  1. 将每个messages模型的Conversation属性映射到使用messages.all().toModelArray()Messages数组中。这给了我错误的Can't mutate a reverse many-to-one relation,即使我试图克隆对象。
  2. 创建一个全新的普通旧JavaScript对象并复制所有属性,然后为messages设置正确的值。这是可行的,但是在状态频繁变化的应用程序上创建所有这些新对象似乎是一个巨大的性能限制。

我应该如何在这里实现我的目标?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2017-12-21 04:49:51

你应该能够做一些类似于:

代码语言:javascript
复制
return session.Conversation.all().toModelArray()
  .map(c => ({
    ...c.ref,
    messages: c.messages.toRefArray()
  }))

在你的选择器里。如果这不起作用,您可能需要包括更多的细节。使用初始的toModelArray不是免费的,您需要“查询”它们才能在选择器中使用它们。

通常,我不会只是像这样转储这些实体的整个存储内容,我会将它们细化到组件实际需要的内容:

代码语言:javascript
复制
import { pick } from 'lodash/fp'

// ...

const refineConversation = c => ({
  ...pick([ 'id', 'updatedAt' ], c),
  messages: c.messages.toRefArray().map(refineMessages)
})

const refineMessages = m => ({
  ...pick([ 'id', 'author', 'text', 'updatedAt' ], m)
})

// ...

return session.Conversation
  .all()
  .toModelArray()
  .map(refineConversation)

虽然从组件的存储中抛出一个对象引用是很有诱惑力的,但是在该对象上有很多东西您的组件可能不需要呈现。如果有任何变化,组件必须重新呈现,并且您的选择器不能使用其回忆录数据。

记住,当您使用对象扩展(或Object.assign)时,您正在创建浅拷贝。是的,这是有代价的,但是任何超过第一级嵌套的都是使用引用,所以您就是不是克隆整件事。选择器的使用应该保护您不必在mapStateToProps中做太多的工作(在使用该数据进行第一次呈现之后)。

使用状态管理做出好的选择是很重要的,但是真正的性能影响可能来自其他来源(不必要的呈现、等待API交互等等)。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47913038

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档