嵌套化简器
Nested reducers
为了学习Redux,我正在启动一个简单的Web应用程序。
如果有验证用户名和密码的"身份验证"操作。然后,我想调用"登录"或"失败"操作。我不知道怎么做。我可以调用身份验证步骤,但不执行嵌套/后续调用。
如何从另一个函数中调用一个函数?(这就是我的问题如何归结为令人沮丧^^)
我的代码如下所示:
function authenticateClient(state, client){
if (client.password === 'perfectsec')
return dispatch(Actions.connectClient(client));
else
return dispatch(Actions.refuseClient(client));
}
在化简器中调用调度不正确。最简单的方法是直接调用函数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}));
化简器不应该调度动作,或者做任何其他有副作用的事情。一个化简器应该只是状态和动作的纯函数(实际上是state + action = newState
) - 整个 Redux 库都是围绕这个假设构建的,我相信它是专门为在化简器内调用调度而引发错误的。
有条件地调度操作的最佳方法是创建一个新的"操作创建者" - 您的应用程序中已经有以下几个:
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));
您的逻辑将运行,并调度适当的操作,而不必损害化简器的纯/同步性质。您的化简器所要做的就是在操作进入时读取它们,并适当地更新状态 - 它不必关心导致操作发生的逻辑。
- 用嵌套函数和默认函数定义函数
- 如何在ReactJS JSX中执行嵌套的if-else语句
- 可以简化嵌套的延迟Q Promises解析吗
- 用于搜索的聚合物嵌套绑定
- 如何使用javascript获取嵌套对象中所有子对象的单个属性
- d3中堆栈函数和嵌套函数之间的差异
- 如何打印嵌套对象的所有值
- JavaScript 中的嵌套函数和 “this” 关键字
- 设置嵌套对象属性的更好方法
- querySelector/getElementByClassName嵌套项的顺序
- 猫鼬在特定记录中查找嵌套记录
- 访问嵌套JSON对象的键,其中键是动态的
- D3嵌套组作为x轴
- Ionic和angularjs嵌套步骤应用程序
- 从多维嵌套json数组创建下拉列表
- 默认情况下折叠和展开嵌套列表
- 嵌套对象结构
- 显示嵌套窗体
- 带嵌套json的下划线js查找
- 如果类不是一个选项,如何在使用 jQuery 时控制(避免)嵌套 html 元素的样式