在传奇内

时间:2017-12-27 04:35:22

标签: javascript reactjs react-redux redux-saga

Noob,只是学习React,React Redux和Redux Saga。

我偶然发现了一个特定情况。

考虑:

我有一个ToDo应用程序,显然这个应用程序由各种组件组成。 有一个特定的状态仅适用于特定组件。(这将是踢球者)

实施例。在这种情况下,模式。基本上它决定了如何显示特定的待办事项(编辑模式普通模式)。

现在我正在使用redux saga来处理所有会导致副作用的代码(在这种情况下是ajax进程)。

现在,如果我单击列表项的编辑按钮,我将该特定列表项模式状态设置为编辑,这将列表项的外观更改为文本框以允许编辑列表项标题。

它还会显示一个新按钮,保存按钮以保存更改,取消按钮取消更改并恢复到正常模式。

编辑标题后,我可以点击保存按钮,当我点击保存按钮时,它会触发我的根传奇听的动作( EDIT_TODO ) 我的root saga然后选择动作并路由到相应的工作者传奇来执行todo项目的实际编辑(涉及ajax请求)

现在这就是罪魁祸首

我想仅在ajax操作成功时执行特定操作(如果通过ajax 成功编辑),并且将列表项的状态从编辑更改为正常。

我如何在传奇中做到这一点?

实际上有两种方式。

1.。)将您的所有应用状态设置为您的redux商店中的状态,这样您就可以创建一个动作,您的传奇(和其他组件)可以触发一个动作,如果它,您的组件将对其采取行动改变了。

这种方法只在某种程度上是可行的,是的,可能存在一个通常在您的组件中共享的状态,但也有一种状态仅对特定组件非常具体。

在这些情况下,仅仅将非常具体的状态添加到redux存储中就没有意义了,因此传奇可以为它启动一个动作。

2.。)在动作有效负载上包含一个函数回调。

所以在我的前任。当单击保存按钮时,当我触发我的根传奇正在侦听的相应操作时,我将包含一个将列表项设置为正常模式的回调。

然后在实际编辑todo项目的saga内部,当ajax操作正常时,调用该回调。

为了澄清,我与动作有效负载一起传递的回调是一个仅改变该特定组件的本地状态的回调(模式

所有全球州(在redux商店注册)都只通过减速器进行了更改。

对我而言,心理上感觉不对?我不知道,但是sagas只是生成器,而异步编程环境中生成器的目的是使异步查看代码在某种程度上看起来是同步的(非常基本类比的生成器 )做这个回调的事情对我来说不对吗?或者不适合这种方法?或者有点像打破发电机(sagas)的目的?

我知道这可能有助于我认为,该回调只是该动作的数据或有效负载的一部分,而不是将其视为回调,但至少对我来说仍然不适合。

或者我只是在这里挑剔?

除了上述内容之外,还有其他替代方案吗?

我想我的问题是,

有没有办法让一个组件听一个动作?然后,如果该动作在任何组件或传奇的任何地方被触发,该特定组件将获取该动作,那么该特定组件将改变其特定状态作为回报吗?

我不确定这个问题是否有意义,或者说这是正确的方法。我只是这个主题的新手,所以请放轻松我。

先谢谢。

1 个答案:

答案 0 :(得分:-1)

传奇的一个非常酷的事情是你可以将许多传奇挂钩到一个动作,但是你也可以从一个传奇中发出其他动作。让我们说你的EDIT_TODO(我将这个重命名为UPDATE_TODO并在踢开编辑模式时使用EDIT_TODO)动作会触发下面的更新传奇。

export function* update(api, action) {
  const { item } = action;
  const response = yield call(api.update, item)
  if (response.data) {
    // Dispatches action for success EDIT_TODO_SUCCESS
    yield put(updateSuccededActionCreator(item));
  } else {
    const error = response.error;
    // Dispatches action for success EDIT_TODO_FAILURE
    yield put(updateFailedActionCreator(item));
  }
}

另外要澄清一点,你可以使用combineReducers redux api来" merge"不同的切片到一个商店。因此,您可以按照自己的方式设计商店,并且切片可以只保存应用特定部分的数据。类似的东西:

const reducer = combineReducers({
  todoState: todoReducer,
  sessionState: sessionReducer
});