javascript - 嵌套 reducer

标签 javascript redux reducers

为了学习 Redux,我正在启动一个简单的 Web 应用程序。

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

如何从一个函数中调用另一个函数? (这就是我的问题如何令人沮丧^^)

我的代码如下所示:

function authenticateClient(state, client){
    if (client.password === 'perfectsec')
        return dispatch(Actions.connectClient(client));
    else
        return dispatch(Actions.refuseClient(client));
}

在 reducer 中调用调度是不正确的。最简单的方法是直接调用函数 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}));

最佳答案

Reducers 永远不应该调度 Action ,或者做任何有副作用的事情。所有 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);
  }
}

同样,这个函数实际上没有调度任何东西 - 它只是返回一个 Action ,您可以在闲暇时调度它,如下所示:

dispatch(connectClientIfValid(client));

您的逻辑将运行,并且会调度适当的操作,而不必损害您的 reducer 的纯/同步性质。您的 reducer 所要做的就是读取传入的操作,并适本地更新状态 - 它不必关心导致操作发生的逻辑。

关于javascript - 嵌套 reducer ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36136051/

相关文章:

javascript - Google Visualization API - 图表未显示

javascript - jquery提交表单问题

javascript - 清理 Redux 状态

reactjs - React Router 用户角色的最佳实践 (Firebase)

javascript - 按名称属性动态信息列出计数数组

javascript - 我试图让 Canvas 元素随着键盘移动

javascript - redux-form - 未捕获错误 : `mapDispatchToProps`

redux - 添加属性reducer redux

mapreduce - 组合器和 reducer 可以不同吗?

Javascript:无法设置未定义的属性;使用函数作为类