Javascript 嵌套异径管

Javascript 嵌套异径管,javascript,redux,reducers,Javascript,Redux,Reducers,为了学习Redux,我启动了一个简单的web应用程序 如果存在验证用户名和密码的“身份验证”操作。然后我希望调用“登录”或“失败”操作。我不知道该怎么做。 我可以调用身份验证步骤,但不会执行嵌套/后续调用 如何从另一个函数中调用函数?(这就是我的问题的症结所在^^) 我的代码如下所示: function authenticateClient(state, client){ if (client.password === 'perfectsec') return dispa

为了学习Redux,我启动了一个简单的web应用程序

如果存在验证用户名和密码的“身份验证”操作。然后我希望调用“登录”或“失败”操作。我不知道该怎么做。 我可以调用身份验证步骤,但不会执行嵌套/后续调用

如何从另一个函数中调用函数?(这就是我的问题的症结所在^^)

我的代码如下所示:

function authenticateClient(state, client){
    if (client.password === 'perfectsec')
        return dispatch(Actions.connectClient(client));
    else
        return dispatch(Actions.refuseClient(client));
}
在减速机中调用dispatch不正确。最简单的方法是直接调用函数
connectClient(state,client)
refuseClient(state,client)
。但这一步不会经过redux流程。


上下文代码:

/* actions.js */

export function authenticateClient(client) {
  return { type: Types.authenticateClient, client };
}

export function connectClient(client, isNew) {
  return { type: Types.connectClient, client, isNew };
}

export function refuseClient(client) {
  return { type: Types.refuseClient, client };
}


/* main.js */

/* reducer */
const reducer = (state = loadState(), action) => {
  console.log(chalk.red(`*${action.type}*`));
  switch (action.type) {
    case Actions.Types.authenticateClient:
      return authenticateClient(state, action);
    case Actions.Types.connectClient:
      return connectClient(state, action);
    case Actions.Types.refuseClient:
      return refuseClient(state, action);
    default:
      return state;
  }
};


/* store */
store = createStore(reducer);


/* app */
store.dispatch(Actions.authenticateClient({username, password}));

减速机永远不应该调度动作,或者做任何有副作用的事情。所有的reducer都应该是一个纯状态和动作的函数(实际上是
state+action=newState
)-整个Redux库都是基于这个假设构建的,我相信它是专门设计的,如果您试图在reducer内部调用dispatch,就会抛出一个错误

有条件地分派操作的最佳方法是创建一个新的“操作创建者”-您的应用程序中已经有了其中一些:

export function authenticateClient(client) {
  return { type: Types.authenticateClient, client };
}

export function connectClient(client, isNew) {
  return { type: Types.connectClient, client, isNew };
}

export function refuseClient(client) {
  return { type: Types.refuseClient, client };
}
请注意,标准动作创建者不会自行分派动作。它们只是返回一个动作的函数,您可以在某个时刻调度自己(如果您想创建一个动作并在实际发送之前保持一段时间,这很方便)。一旦你开始编写异步动作创建者,事情就会变得有些混乱,但这并不在你的问题范围之内,所以我现在跳过它(不过我建议你阅读文档的异步部分!一旦你了解了它,你可以做一些非常酷的事情)

这里要表达的是一个函数,它说,“如果条件为真,请给我一个
connectClient
操作,如果不是,请给我一个
refuseClient
操作”。我们已经知道,提供动作的函数是动作创建者,这就引出了这个答案的要点:动作创建者可以有逻辑。虽然90%的用户只需接收数据并立即返回对象,但这并不是他们可以采用的唯一形式。下面是如何表示此功能的示例:

export function connectClientIfValid(client) {
  if (client.valid === true) {
    return connectClient(client);
  }
  else {
    return refuseClient(client);
  }
}
同样,此函数实际上没有发送任何内容-它只返回一个动作,您可以在空闲时发送该动作,如下所示:

dispatch(connectClientIfValid(client));

您的逻辑运行,相应的操作被调度,而不必牺牲减速机的纯/同步特性。您的reducer所要做的就是在动作进入时读取它们,并适当地更新状态-它不必关心导致动作发生的逻辑。

reducer不应该分派动作,或做任何其他有副作用的事情。所有的reducer都应该是一个纯状态和动作的函数(实际上是
state+action=newState
)-整个Redux库都是基于这个假设构建的,我相信它是专门设计的,如果您试图在reducer内部调用dispatch,就会抛出一个错误

有条件地分派操作的最佳方法是创建一个新的“操作创建者”-您的应用程序中已经有了其中一些:

export function authenticateClient(client) {
  return { type: Types.authenticateClient, client };
}

export function connectClient(client, isNew) {
  return { type: Types.connectClient, client, isNew };
}

export function refuseClient(client) {
  return { type: Types.refuseClient, client };
}
请注意,标准动作创建者不会自行分派动作。它们只是返回一个动作的函数,您可以在某个时刻调度自己(如果您想创建一个动作并在实际发送之前保持一段时间,这很方便)。一旦你开始编写异步动作创建者,事情就会变得有些混乱,但这并不在你的问题范围之内,所以我现在跳过它(不过我建议你阅读文档的异步部分!一旦你了解了它,你可以做一些非常酷的事情)

这里要表达的是一个函数,它说,“如果条件为真,请给我一个
connectClient
操作,如果不是,请给我一个
refuseClient
操作”。我们已经知道,提供动作的函数是动作创建者,这就引出了这个答案的要点:动作创建者可以有逻辑。虽然90%的用户只需接收数据并立即返回对象,但这并不是他们可以采用的唯一形式。下面是如何表示此功能的示例:

export function connectClientIfValid(client) {
  if (client.valid === true) {
    return connectClient(client);
  }
  else {
    return refuseClient(client);
  }
}
同样,此函数实际上没有发送任何内容-它只返回一个动作,您可以在空闲时发送该动作,如下所示:

dispatch(connectClientIfValid(client));

您的逻辑运行,相应的操作被调度,而不必牺牲减速机的纯/同步特性。您的reducer所要做的就是在动作出现时读取它们,并适当地更新状态-它不必关心导致动作发生的逻辑。

我不能100%地理解您的代码,所以请澄清一下-您不是在试图从reducer内部调度动作,是吗?因为那是你100%不应该采取行动的地方。谢谢。是的,这正是我想要做的。我注意到这是不正确的。但我不知道如何实现我的目标。我添加了一段,试图澄清。如果您需要有条件地分派操作,此逻辑很可能位于另一个操作创建者中(例如
操作.connectclientivalid(客户端)
)-如果输入有效,则返回
操作的结果。connectClient(客户端)
,否则,返回
操作的结果。refuseClient(客户端)
。然后,您可以分派返回的任何内容。您的reducer应该做的只是
状态+操作=新闻状态
——它不应该对应用程序的其余部分产生副作用。也就是说,如果需要,它会变得更复杂一些