我有一个使用Oauth2"重定向流程的应用程序"验证用户,即用户被重定向到另一个网站登录,然后重定向回我的网站。
文档和其他来源似乎都声称业务逻辑应该在动作创建者或减速器中。但是我有一个login()
函数不会以任何方式更改状态,它的作用是将应用程序的当前状态保存为localStorage中的普通对象,然后将用户重定向到授权服务器。当用户登录并重定向后,状态将被恢复(通过另一段代码)并作为初始状态提供给我的商店创建者功能。
我的问题:login
函数的逻辑只检索状态但不以任何方式更改它,因此它不属于reducer。它也不会返回动作,动作是动作创建者的定义。在我的应用程序结构中应该放在哪里?
好吗"好的"有一个实际上没有创建动作的动作创建者?我现在正在使用redux-thunk执行此操作(因为我需要getState()
)并且它没有任何问题,但它感觉不对,因为它实际上不是"动作创建者& #34;,另一方面,我也有一个logout()
函数确实返回一个动作,所以感觉它们应该住在同一个地方。我认为这是一个极端情况,但并不是因为我能想出很多理由以这种方式保存状态并将访问者重定向到其他网站(甚至只是保存状态而不重定向)。 / p>
PS。我知道有些库可以自动将我的redux存储与localStorage同步,但这不是问题的关键。
编辑:一些澄清:
从Redux docs关于业务逻辑的放置位置: 对于缩减器或动作创建者应该采用哪些逻辑,没有一个明确的答案。
请继续阅读,它明确指出我只有两个地方可以放置业务逻辑,无论是在减速器还是动作创建器中。现在,既然我想要做的事情并没有影响状态,而且根据定义,减速器会影响状态,我倾向于将这个逻辑放在一个动作创建者身上。
关于动作创建者的文档:动作创建者正是创建动作的功能。将“行动”和“行动创造者”这两个术语混为一谈很容易,所以尽量使用正确的术语。 [...]在Redux中,动作创建者只需返回一个动作
有关操作的文档:操作是纯JavaScript对象。
我登录示例的伪代码:
function login() {
// retrieving and serializing the state, then:
localStorage.set('my_app_id_state', my_serialized_state);
window.location = url_to_authorization_service;
}
此代码显然在动作创建者中没有位置,因为我没有返回动作,这是动作创建者的目的。但是我仍然需要检索状态,这样我才能完全独立。
同样,问题是我将这段代码放在我的应用程序结构中?
同样,代码有效,一切都很好,所以我想这更像是一个学术问题,但它让我很烦恼,我在这里明显违反了Redux的基本规则。也许它只是一个例外?
答案 0 :(得分:0)
这是一个很好的问题,并且意识到我做错了什么。所以希望这个答案至少对两者都有帮助:))
将此示例改编自Real World Redux example:
私人功能
function oauth(url) {
return (dispatch) => {
dispatch({
type: types.OAUTH_LOGIN,
url
});
};
}
由动作创建者(返回一个函数)调用
export function loginToApi(redirectUrl) {
return (dispatch) => {
return dispatch(oauth(redirectUrl))
}
}
然后在组件中调用该动作,如下所示:
login() {
return this.props.dispatch(loginToApi());
}
因此,回答您问题的一种方法是将您的业务逻辑放在私有方法中,然后由操作创建者调用。
可能有更优雅的方式,但这就是我在上面提到的文档中的完成方式。
关于将状态存储在本地存储中的登录逻辑:我认为您不需要这样做。 Redux商店正在为您管理州。
答案 1 :(得分:0)
Dan Abramov在Twitter上回复,我将得出结论,这是文档中概述的规则的例外。