我应该在 Redux 中存储 Promise 吗?

Posted

技术标签:

【中文标题】我应该在 Redux 中存储 Promise 吗?【英文标题】:Should I store promises in Redux? 【发布时间】:2017-07-15 16:20:21 【问题描述】:

我在一个在线订餐应用中使用 Redux 和 React。

当用户从他们的购物篮中取出一件商品时,我需要向服务器发出 XHR 请求以计算购物篮的新总价。当这个 XHR 完成时,我会更新 redux 存储并呈现新价格。我正在使用 Redux thunk 来管理这个异步操作。

有一个问题是用户快速连续地从篮子中删除了两个项目。用户删除了第一个项目,我启动了 XHR 以获得新价格。然后用户点击一个按钮来移除第二个项目,第二个 XHR 被触发。

如果第二个 XHR 在第一个之前完成,则 UI 将处于错误状态 - 将显示仅删除第一个项目的篮子的价格。

要解决此问题,我想在用户单击按钮删除第二个项目时取消第一个(正在运行的)XHR。要取消第一个 XHR,我需要跟踪 promise 对象(我使用 axios 来管理 XHR)。

将飞行中的 XHR 存储在 redux 存储中对我来说很有意义。像这样在 Redux 中存储 Promise 是不好的做法吗?似乎不赞成 - Redux 应该只存储普通数据。

【问题讨论】:

这是我第一次听说在 Redux 应用状态中存储 Promise。我认为可能有比这更好的方法。为什么不阻止用户在发出请求时做任何事情(例如,通过显示加载图标来禁用做任何事情的能力)?我认为提出一个更简单的解决方案是最好的。如果你真的想取消承诺,请查看本页底部:https://facebook.github.io/react/blog/2015/12/16/ismounted-antipattern.html。或者你可以看看 RxJS。 使用 redux-observable github.com/redux-observable/redux-observable 可以快速工作,这里可以用史诗替换你的一个 thunk 【参考方案1】:

这在 Redux 常见问题解答中有所介绍,http://redux.js.org/docs/faq/OrganizingState.html#organizing-state-non-serializable:

强烈建议您只将普通的可序列化对象、数组和原语放入您的存储中。从技术上讲,可以将不可序列化的项目插入到 store 中,但这样做会破坏持久化和重新水化 store 内容的能力,并干扰时间旅行调试。

通常,任何像这样的异步行为都是在 Redux 存储外部处理的,通过 promises 或中间件,如 redux-thunk、redux-saga 或 redux-observable。有关这些方法之间的一些比较,请参阅最近的文章 Redux 4 Ways 和 3 Common Approaches to Side-Effects in Redux。

【讨论】:

以上是关于我应该在 Redux 中存储 Promise 吗?的主要内容,如果未能解决你的问题,请参考以下文章

React + Redux + Router - 我应该为所有页面/组件使用一个状态/存储吗?

Redux - 我应该从状态或 api 调用中获取产品详细信息吗?

Redux-Promise 不会阻止被拒绝的 Promise

如何在 reducer 中处理 Redux 的 redux-promise 中间件 AJAX 错误?

在 react-redux-promise 应用程序中解析 XML

异步 redux 函数如何工作?