【问题标题】:Structuring redux, redux-saga and normalizr构建 redux、redux-saga 和 normalizr
【发布时间】:2017-01-23 10:38:22
【问题描述】:

所以我想使用这三种技术。我的想法是在 normalizr 的帮助下拥有一个处理我所有实体的 reducer。

redux-saga 会监听 ENTITIES_REQUESTED 动作,运行一个请求实体的 saga,并执行一个 ENTITIES_RECEIVED 动作,这将由调用 normalizr 并将实体存储在 entities 切片中的 reducer 处理.

要删除一个实体,有两件事必须发生:必须从状态中删除该实体,并且必须发生一个副作用,该副作用将从服务器中删除该实体(旁白:我知道有些人会声称从状态中删除也是一个副作用,但我不认为 redux-saga 在这个概念上起作用)。

所以我可以有一个ENTITY_REMOVED 操作,它将从状态中删除实体,以及一个监听它的 saga,它将处理 api 调用。

现在假设我有一个表,该表具有批量删除功能。该表由接受动作DATA_OPTIONS_SET 的减速器“供电”。 reducer 会更新当前页面、过滤器等内容。还会有一个 saga 来自监听此内容并调用 API 以返回新数据集。

我想要一个批量删除功能,它在较高级别删除所有实体,完成后刷新表格。

如果我遍历要删除的实体,并发送 ENTITY_REMOVED 操作,我将无法知道这些删除何时完成,以便我可以刷新表。

如果我手动调用删除实体的 saga,ENTITY_REMOVED 将永远不会被调度,因此实体不会从存储中删除。

这是否意味着我的架构不正确,我在某个地方走错了路?

【问题讨论】:

    标签: redux redux-saga normalizr


    【解决方案1】:

    我将按如下方式处理您的问题:创建删除传奇

    1. 等待以实体 ID 作为参数的 ENTITIY_REMOVE_REQUEST 操作
    2. 调用适当的端点以从服务器中删除实体
    3. 如果 api 调用成功,则调度 ENTITY_REMOVED 操作,该操作将从状态中删除实体。

    当然,这不是唯一的选择,很多细节将取决于你的 api 是如何构建的。而不是在第 3 点手动删除每个实体。您可以调度一个操作,该操作将从服务器获取所有实体并使用新实体列表更新您的整个状态,或者您可以批量化并传递所有需要在单个 api 中删除的实体调用第 2 点。

    【讨论】:

    • 我不喜欢 ENTITY_REMOVE_REQUEST 的一点是,它是对应用程序状态没有意义的操作。它的唯一目的是产生副作用,这对我来说似乎很尴尬。
    • 就应用程序的状态而言,它表示可能失败的操作(或计算)序列。因为您只想在对服务器的网络请求成功时更新您的状态。如果您不检查网络操作是否成功,您的应用程序状态可能与服务器上的状态不同。我认为这样的组织会导致非常明确的 sagas,但是如果您找到更好的解决方案,我会很乐意学习
    • 我认为 saga 可以通过在出现问题时简单地发出补偿动作来处理失败的情况。
    • 我不确定我是否理解正确:您继续通过删除一个项目来更新 redux 状态,这将使您的一些组件重新呈现。接下来,您进行 api 调用,如果它失败,您会触发额外的操作来添加刚刚从状态中删除的项目?这似乎相当复杂,因为您必须存储要删除的临时项目,这会使您的组件闪烁,我认为这会让用户感到困惑。看看 redux-saga 真实世界的例子。他们似乎正在为任何 api 调用发出请求操作并发出成功/失败操作作为后续操作。
    • 流程如下所示: 1) 从 redux 状态中移除实体 2) 触发 API 调用的副作用 3) 如果出现问题,我们会通知用户,并将实体重新放入国家。 UI 完全乐观,服务器完全透明。