2 sagas更新同一对象时更新redux商店?

时间:2017-11-07 17:31:47

标签: reactjs redux react-redux

我有一个自动推荐组件,可以显示搜索结果。在点击结果时,我正在触发一个动作SEARCH_RESULT_CLICKED,后者又会调用两个传奇。

Saga 1,获取结果的text,并触发带有效负载的操作ITEM_SUMMARY_FETCHED

{ text: ... }

将其显示在组件中,例如B为ITEM_SUMMARY_FETCHED实现减速器。

Saga 2,获取结果的id,然后进行API调用。获取结果后,它会触发ITEM_SUMMARY_FETCHED并将有效负载作为

{ description : ... }

预计组件B将显示文本和说明。所选结果, 减速器有点像这样:

case 'ITEM_SUMMARY_FETCHED':
  return {
    ...state.itemdetails,
    ...action.summary,
  };

我希望这些属性能够合并,但它不会这样做。当Saga 2触发操作时,stateundefined。因此,文本的值将被删除,只显示描述。

任何人都可以帮助我解决我可能出错的地方吗?

1 个答案:

答案 0 :(得分:0)

在您的场景中是否可以从另一个内部调用一个saga并组成一个您要发送到store的单个对象。这是我想象的工作流程:

  1. SEARCH_RESULT_CLICKED只调用你的第一个传奇。
  2. 那个传奇中,调用你的第二个传奇。您的生成器应暂停并等待API完成提取请求 数据。
  3. 撰写一个包含textdescription字段的单个对象(在您的第一个传奇中),text来自 来自API请求的actiondescription (并从你的第二个传奇回来。
  4. 使用此重构对象从您的第一个传奇中发送单个操作。这只会更新store一次。
  5. 这是我经常使用的模式 - 从另一个中调用一个传奇。对于传奇可重用性来说它并不是很好,因为它假设这些传奇将永远在一起运行。但如果这是您正在寻找的情景,那么这可能会奏效。

    您还可以考虑使用yield all并行运行任务:https://redux-saga.js.org/docs/advanced/RunningTasksInParallel.html

    修改

    根据您对有两个不同事件的评论,您可以查看有关fork的{​​{3}}。使用fork将在您的传奇中启动非阻止任务,因此您不必等待API返回。你只需:

    1. yield fork(CALL_TO_API) - 这将启动API调用,但不会阻止。
    2. yield put(ACTION_TO_UPDATE_TEXT) - 这将使用文本更新Redux。
    3. yield take(REFERENCE_TO_API_CALL) - 这将等到CALL_API返回。
    4. yield put(ACTION_TO_UPDATE_DESCRIPTION_WITH_API_RESPONSE) - 这将使用API​​中的描述返回数据更新Redux。
    5. 以这样的方式更新UI并不是很好 - 通常最好在更新UI之前等待所有数据到达。您可能需要进行一些API优化以找出解决问题需要3-5秒的原因。祝你好运!