使用离线 Firestore 与 Redux 的最佳方法是什么?



tl;dr在尝试更新后端数据库(例如 Firestore(之前更新 redux 存储是否是一种好习惯,或者是否有其他"最佳实践"解决方案?

目前,我已经创建了一个使用创建反应应用程序的应用程序。 后端数据存储在Firestore上。 当应用加载时,最初,它会从 Firestore 获取项目数组,并将它们加载到 UI 用于呈现内容的 Redux 存储中。

一切都很好。

我的问题是关于如何在离线时实施 CRUD 操作(例如创建项目(。 作为记录,CRA正在缓存应用程序,以便UI离线工作(如果商店中有数据(,所以我的问题不是关于这个,而是关于最好将数据发送到Firebase并将(相同的(有效负载发送到redux商店的顺序。

请注意,下面的"db"是一个Firestore连接的数据库(在其他地方配置(,当我谈论离线使用Firestore时,我说的是enablePersistence,这是iOS和Android的默认数据库。 我正在使用Thunk。

例如,我看到一个常见的 Redux 操作创建者模式,如下所示。 在这种情况下,我正在使用它来创建一个新项目:

export const createProject = projectData => async dispatch => {
dispatch({ type: CREATE_PROJECT_START });
try {
await db
.collection("projects")
.doc(projectData.project_uid)
.set({ ...projectData });
dispatch({ type: CREATE_PROJECT_SUCCESS, payload: projectData });
} catch (e) {
dispatch({ type: CREATE_PROJECT_FAIL, payload: e.message });
}
};

这种行为使得在从 Firebase 返回承诺之前不会将有效负载调度到 Redux。

在测试中,我可以关闭网络并创建一个新项目。 当 createProject 函数被调用(通过表单提交(时,控制台会亮起 net::ERR_INTERNET_DISCONNECTED 消息,这是预期行为。

但是,当用户从表单返回到呈现所有项目的页面时,新项目不会呈现,因为 Firebase 承诺尚未完成。

然而,令人敬畏的是,当我重新打开网络时(我只测试了几分钟,我不确定这在很长一段时间后会有多好(,Firebase 会抓住它在线的事实,发送数据,返回承诺,然后可以调度到 Redux。

虽然很棒,但它不是最好的用户体验,所以我实现了如下所示的小调整:

export const createProject = projectData => async dispatch => {
dispatch({ type: CREATE_PROJECT_START });
try {
dispatch({ type: CREATE_PROJECT_SUCCESS, payload: projectData });
await db
.collection("projects")
.doc(projectData.project_uid)
.set({ ...projectData });
} catch (e) {
dispatch({ type: CREATE_PROJECT_FAIL, payload: e.message });
}
};

通过在数据库上调用 set 方法之前简单地将调度移动到 Redux,行为要好得多,因为项目在 UI 中创建后会立即呈现给用户。 事实上,用户可以执行一些更改,这些更改都正确反映在 UI 中,即使数据库正在脱机工作也是如此。

错误仍然在控制台中消失,再次在意料之中。 当重新建立网络连接时,Firestore 确实会在后台接收数据。

那么,说了这么多,在数据库更新之前将调度到 Redux 是一种好/坏的做法,和/或者有更好的方法来做到这一点吗?

最近自己遇到了这个问题,最初做了错误的事情,所以虽然痛苦/教训仍然新鲜。

Firestore 使用的同步模型是 Promise 的解决方案旨在为开发人员提供处理拒绝失败的机会;无论是立即,还是在将来某个时候应用程序重新上线时,例如让开发人员有机会重试或回滚更改。

若要有效地使用此错误处理机制,会导致状态模型,其中应用本地状态必须引导中心状态。

回答有关 Redux 最佳实践的问题。只要它的Reducers保持"纯净",当外部副作用发生相对于局部状态操纵时并不重要。

许多不同的 Redux 异步中间件解决方案相对于 Reducers 在不同的点上运行,例如之前的 Thunks 和 Sagas,之后的 Epics,Loops with。我认为这感觉有点奇怪,因为它不是我们习惯使用的。从本质上讲,当它发生时,对于开发人员来说,对于手头的用例来说,这是最有意义的。

我猜问题作者不久前破解了这个问题。但是,一旦了解了Firestore的同步模型,仍然如何最好地处理拒绝,离线性能与大量排队的承诺,处理在没有承诺时失败的后端写入,因为应用程序已重新启动等。

会对经验和实施这些东西的指示非常感兴趣:-(

相关内容

最新更新