我们说我有预订系统的存根。
当我创建预订时,我可以在我们的客户中搜索并选择我预订的客户。在选择客户时,关联的客户联系人被加载为副作用。作为用户,我必须为预订选择其中一个联系人。
让我们假装我的状态是这样的:
{
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个需要触发的副作用。
答案 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原则,允许行为可预测和可维护 - 您不会忘记将其更新到一个地方并破坏内容。更少的代码来测试;)