Redux-Saga的状态变化

时间:2017-04-26 13:40:12

标签: reactjs redux redux-saga

我有一个简单的React App。它允许用户编辑表单以更新数据库中的数据。在提交页面时,生成带有表单数据的操作。 Redux Saga产生动作并异步更新数据库。这一切都有效。

然而,在一个案例中,更新涉及更多。不仅必须添加新数据,而且必须在一系列API调用中从数据库中删除表单上删除的任何数据。要做到这一点,我需要知道发生了什么变化(例如已删除的内容),而不仅仅是新状态。

我的传奇如何才能访问此信息?我可以在reducer中计算它,因为它可以访问先前的状态,但它通常被认为是re​​ducer的反模式然后发送一个新的动作。

2 个答案:

答案 0 :(得分:1)

Sagas有一个select效果,它只运行一个选择器函数并返回提取状态。您可以使用它从Redux商店检索旧项目和新项目,并从那里处理更改:

function* handleFormUpdates() {
    const oldItem = yield select(selectOldItem);
    const newItem = yield select(selectNewItem);

    const changes = diffTheItems(oldItem, newItem);

    // make API calls to deal with changes appropriately
}

总的来说,这是保持"临时"的一个很好的理由。或"草稿"在Redux中,你可以使用" current"和"草案"逻辑中的值。

我在博文Practical Redux, Part 7: Form Change Handling, Data Editing, and Feature ReducersPractical Redux, Part 8: Form Draft Data Management

中讨论了一些相关概念

答案 1 :(得分:0)

  

...在表格上删除的任何数据都必须   通过一系列API调用从数据库中删除。为此,我   需要知道已更改的内容(例如已删除的内容),而不是   只是新状态。

如果我正确理解,您将表单状态保存在redux存储中,那么您需要知道何时以及发生了什么更改。您可以创建自己的观察者传奇:

function* watchFormUpdates(){
  while (true) {
    const oldFormState = yield select(selectors.selectFormState);
    const action = yield take (actionTypes.FORM_UPDATE); // wait until action is dispatched
    const newFormState = yield select(selectors.selectFormState); // at this point store has been updated
    // compare oldFormState with newFormState...
    if(oldFormState.hasSubscription && !newFormState.hasSubscription) {
      yield fork(deleteSubscriptionSaga); // start non-blocking worker task
      // or just dispatch action - yield put(actionCreators.deleteSubscription());
    }
  }
}