Redux商店设计 - 两个数组或一个

时间:2018-02-03 20:46:03

标签: react-native redux react-redux

我想这可以应用于任何Redux支持的系统,但想象我们正在构建支持两个操作的简单React Native应用程序:

  1. 从远程API获取消息列表
  2. 将这些邮件标记为已阅读的能力
  3. 目前我有messagesReducer将其状态定义为......

    const INITIAL_STATE = {
      messages: [],
      read: []
    };
    

    messages数组存储来自远程API的对象,例如......

    messages: [
      { messageId: 1234, title: 'Hello', body: 'Example' },
      { messageId: 5678, title: 'Goodbye', body: 'Example' }
    ];
    

    read数组存储已读取的消息的数字ID以及其他一些元数据,例如......

    read: [
      { messageId: 1234, meta: 'Something' },
      { messageId: 5678, meta: 'Time etc' }
    ];
    

    在列表中显示消息的React组件中,我运行此测试以查看消息是否应显示为正在读取...

    const isRead = this.props.read.filter(m => m.messageId == this.props.currentMessage.messageId).length > 0;
    

    目前这很有用。显然我可以在消息对象上放置一个布尔isRead属性,但上述安排的主要优点是来自遥控器的内容可以覆盖messages数组的全部内容API

    我关注的是这种扩展的程度,以及当数组变大时array.filter方法的成本。另请注意,该应用会显示可能包含数百封邮件的列表消息,因此会对列表中的每封邮件进行过滤。它适用于我现代的iPhone,但在功能不太强大的手机上可能效果不佳。

    我也在想,我可能会错过一些完善的最佳实践模式。

    我们称之为当前方法选项1 。我可以想到另外两种方法......

    选项2 是将isReadreadMeta属性放在邮件对象上。这将使消息列表呈现超快。但是,当我们从远程API获取消息列表时,我们需要逐步完成API返回的JSON并仔细更新和删除本地存储中的消息,而不是仅覆盖当前数组。

    选项3 会保留当前的read数组,但也要在邮件对象上添加isReadreadMeta属性。当我们从远程API获取消息列表时,我们可以覆盖整个messages数组,然后遍历read数组并将数据复制到相应的消息对象中。这也需要在用户阅读消息时发生 - 数据将在两个地方重复。这让我觉得不舒服,但也许没关系。

    我一直在努力寻找这类商店的许多其他例子,但可能就是我只是在谷歌搜索错误的东西。我对Redux很陌生,我的一些术语可能不正确。

    我非常重视对此的任何想法。

2 个答案:

答案 0 :(得分:1)

使用reselect,您可以记住array.filter的结果,以防止在messagesread数组都没有更改时过滤数组,这样您就可以使用选项1

通过这种方式,您可以轻松地将原始数据存储在Reducer中,还可以有效地访问计算数据以进行显示。这样做的一个好处是,您将数据结构和存储的要求与数据显示方式的要求分离开来。

您可以在redux docs

中详细了解如何有效地计算衍生数据

答案 1 :(得分:1)

如何使用查找表对象,其中id是键 这样您就不需要过滤也不需要循环以查看是否存在某个消息ID。只需检查对象是否包含具有相应ID的键:

所以在你的情况下它将是:

const isRead = !!this.props.read[this.props.currentMessage.messageId];

小型运行示例:



const read = {
  1234: {
    meta: 'Something'
  },
  5678: {
    meta: 'Time etc'
  }
};

const someMessage = {id: 5678};
const someOtherMessage = {id: 999};

const isRead = id => !!read[id];

console.log('someMessage is ',isRead(someMessage.id));
console.log('someOtherMessage is ',isRead(someOtherMessage.id));




修改
我建议您阅读redux文档中的Normalizing State Shape 有很多设计和组织数据和状态的例子。