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

时间:2016-06-07 07:29:00

标签: javascript reactjs redux redux-saga

我们说我有预订系统的存根。

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

让我们假装我的状态是这样的:

{
    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个需要触发的副作用。

1 个答案:

答案 0 :(得分:0)

听起来你应该概括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()

我想这更适合你的第一种选择。你应该把这个复杂的调度序列和副作用封装在一个传奇中,你可以用一个动作开始。你有TAKE副作用的复杂传奇阻塞,等待触发该动作。与您找到的in this redux-saga example类似。

创建时有一个这样的序列:

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

加载时这是

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

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