React / Redux 加载具有副作用的数据

Posted

技术标签:

【中文标题】React / Redux 加载具有副作用的数据【英文标题】:React / Redux loading data with side effects 【发布时间】:2016-10-06 23:38:51 【问题描述】:

假设我有一个预订系统的存根。

创建预订时,我可以在我们的客户中搜索并选择我要预订的客户。选择客户后,关联的客户联系人将作为副作用加载。作为用户,我必须选择其中一个联系人进行预订。

让我们假设我的状态形状是这样的:


    customer: id: 1, name: "Dandy Inc"
    customerContacts: [id:1, name: "John Doe",id:2, name: "John Doe"]
    customerContactId: 2

保存时,我只保存 customerId 和 customerContactId。

现在假设我想在未来的某个时间点编辑此预订。

我可以

1) 获取我拥有的数据,并基本上“重播”操作以触发我需要的副作用(例如,设置客户并触发加载客户联系人的副作用) 或

2) 获取我拥有的数据,手动加载我需要的任何额外数据,然后一次性设置完整的应用程序状态。

您对最佳前进路线有何看法?这是一个简化的例子,假设现实世界的场景至少有 2-4 个额外的副作用需要触发。

【问题讨论】:

我认为 Redux 商店应该已经拥有你需要的一切,否则我在你的问题中遗漏了一些东西。 【参考方案1】:

听起来你应该概括create/loadCustomerBooking 功能来处理是否存在customerContactId(非常多的伪代码):

populateCustomerBooking = (customerId, customerContactId) =>
    loadContacts(customerId)
    if (customerContactId) 
        setContactWithSideEffects(customerContactId)
    runOtherCustomerSideEffects(customerId)
    // And so on...

// This is called when a contact is chosen or we're loading.
setContactWithSideEffects = (customerContactId) =>
    dispatch(SET_CUSTOMER_CONTACT)
    runContactSideEffects()

我想这在某种程度上更适合您的第一个选择。您可能应该将这个复杂的调度序列和副作用封装在一个 saga 中,您可以通过一个操作来启动它。您的复杂传奇阻塞了 TAKE 副作用,等待触发该操作。与您找到的 in this redux-saga example 类似。

创建时你有这样的序列:

createBooking -> chooseCustomer -> dispatch(POPULATE_BOOKING(customerId))

加载时会这样

loadBooking -> dispatch(POPULATE_BOOKING(customerId, customerContactId))

您复杂的populateCustomerBooking 传奇正在对POPULATE_BOOKING 操作执行类似于takeEvery 的操作。这允许您重用所有这些逻辑,因为它听起来应该是相同的。在我看来,这种方法更可取,因为它遵循 DRY 原则,允许行为是可预测和可维护的——你不会忘记在一个地方更新它并破坏东西。测试的代码也更少;)

【讨论】:

以上是关于React / Redux 加载具有副作用的数据的主要内容,如果未能解决你的问题,请参考以下文章

React/Redux AG Grid 未加载数据

React Router 和 Redux - 初始加载数据

React + redux:连接组件加载时调用调度

具有关系数据存储的列表和项目之间的关系(使用 react-redux)

React Redux仅从firebase加载一次数据

第一次下载 React 包时 Redux SAGA sideEffect 处理程序不起作用