我有一个登录表单,如果用户的电子邮件存在于数据库中,则需要将用户重定向到登录页面。
我有一个名为“FormToLogin”的类,其方法名为login
。在login
方法中,我将数据和this.props.history
发送到一个名为loginAct
的动作。
容器:
class FormToLogin extends Component {
login = fullForm => {
const { dispatch } = this.props;
const data = {[user]: {...fullForm}}
return dispatch(login(data, this.props.history)) <-- apparently, passing history to an action is not good)
}
}
如您所见,我通过传递数据(其中将包括用户输入的电子邮件地址)和历史记录来调用操作,因为如果数据库中存在电子邮件,我想制作.push('/new_url')
。
行动:
export const login = (data, history, dispatch) => {
return api.post(url, data)
.then(({ status, h, data }) => {
// whatever if it returns 200
}
.catch(({ response }) => {
dispatch(loginFail());
const status = (response || {}).status;
if (status === 401 && hasError(error_user, response.data)) {
history.push('/new_url') // This is INCORRECT
?? -- what do I need here -- ??
}
})
}
我被告知将Route历史传递给Action是不好的做法。所以,history.push()
不应该发生在这里。我被建议在容器级别添加一个catch(“FormToLogin”)。
所以,当我用Container(FormToLogin)
调用Action时,我试图在dispatch(login(data))
中创建一个catch,但它不起作用。此外,容器中不存在var status
。
BEFORE: return dispatch(login(data, this.props.history))
AFTER: .catch(e => {
if (status === 401 && hasError(
error_user,
e.response.data
)) {
history.push('/new_url);
} throw e; })
我需要添加或更改什么?
解决这个问题的两种方法。
1)在没有显式传递的情况下访问Action创建者内部的历史对象。
//创建历史对象
history.js
import createHistory from 'history/createHashHistory'
export default createHistory()
action.js
import history from './history'
history.push('/new_url') // use it wherever you want.
2)如果你不想让它在里面行动,那么在formLogin里面处理它。
调度dispatch(loginFail());
时,在loginFail函数内设置email_address的状态。由于使用props的react-redux库,你可以使用FormToLogin中的connect函数获得该状态。
你可以编写内部渲染功能。
if (this.props.isEmailAddress) { history.push('/new_url') }