如何解决使用 mobx 或 redux 还是使用存储库模式和持久本地存储领域或 sqlite?
Mobx 和 Redux 通常不会保留任何数据。它们将在应用运行时保持一个临时全局状态。
我知道这两个社区中都有 redux-persist
和 mobx-persist
软件包。但不幸的是,这些 persisting
解决方案似乎一点都不好。它们只stringify
或serialize
一个全局状态树并使用某种键值存储来持久化它。对吗?
问题:
当此类应用再次打开时,stringified
存储将被解析并构造回其原始数据结构(例如 JSON),然后完全加载到 RAM 内存中。 我说得对吗?
如果是,这是一个问题。总是在内存中加载一个完整的“数据库”又名“全局状态”是不好的。与在 sqlite 上查询表相比,在我的全局状态中过滤长数组中的数据可能永远不会更快,对吗?
我一直在寻找一些类似 repository
的解决方案,用于为 redux 或 mobx 持久化全局状态。我正在寻找一些解决方案,用于在一些著名的移动数据库(如 sqlite 或其他)上持久化和查询数据。
任何答案将不胜感激。
解决方法
我不太确定您需要什么,但如果我理解正确,您需要保留大量数据,并加载相同的数据,但只能批量。
我相信这种问题可以通过 repository pattern 和 SOLID 设计原则解决。
您将需要:
-
保存您的业务逻辑的商店类(mobx 商店)。
-
负责检索和持久化数据的存储库类。
商店通过构造函数将存储库注入其中。
然后,当您在商店中调用 initialize
方法时,它会与存储库对话并检索初始数据。现在,初始数据只能是所有持久化数据的一个子集。并且您可以在存储和存储库上实现某种分页,以根据需要批量检索数据。稍后您可以根据需要调用其他方法来加载和保存其他数据。
伪代码:
class Repository(){
initialize()// load the first batch
load(next 10 models)
save(data)
}
class Store{
constructor(repository)
initialize(){
repository.initialize()
}
load(){
repository.load()
}
save(){
repository.save()
}
}
现在您的应用程序数据不应该是一个巨大的对象,而应该由多个存储组成,每个存储负责一部分数据。例如,您将拥有一个用于处理 todos 的存储和存储库,以及另一对用于处理 地址簿联系人 等
附录:
将存储库注入到存储中的原因是,您可以轻松地将其交换为其他一些实现(存储不关心数据是如何持久化和检索的)以及单元测试很容易。
您还可以拥有一个 root 存储来保存所有其他存储,因此本质上您可以在一个地方拥有完整的状态。因此,如果您在 serialize
存储上调用 root
,它会序列化所有存储并返回一个大对象。
AFAIK,在 redux persist 中使用 sqlite 有两种选择。
- redux-persist-sqlite-storage:维护者自己的话
默认情况下,redux-persist 在 react-native 中使用 AsyncStorage 作为存储引擎。这是 AsyncStorage 的替代品。 该库的灵感来自于 react-native-sqlite-storage。
请记住,要使用它,您需要安装一个额外的安装包react-native-sqlite-storage
- redux-persist-sqlite:维护者自己的话
一个写入 sqlite 的 redux-persist 存储适配器。 这是改编自 https://github.com/prsn/redux-persist-sqlite-storage,但使用 Node.js sqlite3 而不是 react-native。 非常适合由 Redux 支持的 Electron 应用。
更新:react-native-mmkv:这是由微信开发的。正如它在关于部分中所说的
一个用于 React Native 的极快的键/值存储库。比 AsyncStorage 快 30 倍!
,确实可以使用存储库模式。
在您的存储库中,您可能有一个 save
方法。
save(group: GroupLocalStorageModel): Promise<boolean> {
let created;
this._localStorage.write(() => {
created = this._localStorage.create<GroupLocalStorageModel>("Group",group);
});
return Promise.resolve(true);
}
此方法实际上会将您的实体保存到您设置的某个本地存储中。在上面的示例中,我们将一个 group
对象保存到一个类似于表的 Group 集合中。我们正在使用 realm ,它是 no-sql。
拥有存储库后,如果您使用的是 redux 或 mobx,则可能会在操作上调用 save
方法。 redux 和 mobx 都支持动作,对吧?
export const GroupStoreModel = types
.model("GroupStore")
.props({
groups: types.optional(types.array(GroupModel),[]),})
.extend(withEnvironment)
.actions((self) => {
return ({
_addGroupToStore(group: GroupLocalStorageModel) {
self.groups.push(group)
},_deleteAllFromStore() {
self.groups.clear()
},_addGroupsToStoreBatch: (groups: GroupLocalStorageModel[]) => {
self.groups.concat(groups);
},})
})
/* Async actions */
.actions((self) => {
let groupRepository = self.environment.groupRepository;
return ({
addGroup(group: GroupLocalStorageModel) {
groupRepository.save(group).then(result => self._addGroupToStore(group))
},getAllGroupsPaginated(page: number) {
groupRepository.getAllPaginated(page).then(groups => self._addGroupsToStoreBatch(groups));
},deleteAll() {
groupRepository.deleteAll();
self._deleteAllFromStore();
}
})
})
在本例中,我们使用 mobx-state-tree
。而这个 addGroup
操作将首先更新我们的数据库,然后更新全局状态。
我们仍然希望使用我们的全局状态,因此我们的视图将根据 connect
for redux 或 observable
for mobx 自动重新呈现。
在此处查看有关存储库的更多信息:
https://github.com/Hadajung/poc-react-native-database-example
,我认为最好的解决方案是来自 flutter_bloc 的 bloc hydrated
或 cubit hydrated
包。
https://pub.dev/packages/hydrated_bloc
在后台它使用 Hive DB,非常高性能的 DB,并且只有键存储在内存中,所以它不应该像 SQLite 那样给应用程序增加巨大的膨胀。 如果您可以以块/肘为单位制作所有 APP 逻辑,那么额外的数据库调用将无关紧要。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。