我想这可以应用于任何Redux支持的系统,但想象我们正在构建支持两个操作的简单React Native应用程序:
目前我有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 是将isRead
和readMeta
属性放在邮件对象上。这将使消息列表呈现超快。但是,当我们从远程API获取消息列表时,我们需要逐步完成API返回的JSON并仔细更新和删除本地存储中的消息,而不是仅覆盖当前数组。
选项3 会保留当前的read
数组,但也要在邮件对象上添加isRead
和readMeta
属性。当我们从远程API获取消息列表时,我们可以覆盖整个messages
数组,然后遍历read
数组并将数据复制到相应的消息对象中。这也需要在用户阅读消息时发生 - 数据将在两个地方重复。这让我觉得不舒服,但也许没关系。
我一直在努力寻找这类商店的许多其他例子,但可能就是我只是在谷歌搜索错误的东西。我对Redux很陌生,我的一些术语可能不正确。
我非常重视对此的任何想法。
答案 0 :(得分:1)
使用reselect,您可以记住array.filter
的结果,以防止在messages
或read
数组都没有更改时过滤数组,这样您就可以使用选项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
有很多设计和组织数据和状态的例子。