我正在尝试根据Redux存储中的isLoggedin状态登录用户。我的登录组件从映射到道具的userLogin动作调度fetchLogin动作。
const Login = (props) => {
const [userLogin, setUserLogin] = useState({ email: "", password: "" })
const getValue = e => {
e.preventDefault();
setUserLogin({
...userLogin,
[e.target.name]: e.target.value
});
}
const makeRequest = (e) => {
e.preventDefault()
props.userLogin(userLogin)
if (props.isLoggedin === true) {
console.log(Cookie.get('accessToken'))
props.history.push('/dashboard')
}
}
return (
<Fragment>
<Form onSubmit={makeRequest}>
<Form.Group controlId="formBasicEmail">
<Form.Label>Email Address</Form.Label>
<Form.Control
type="email"
name="email"
placeholder="Enter email"
onChange={getValue}
>
</Form.Control>
</Form.Group>
<Form.Group controlId="formBasicPassword">
<Form.Label>Password</Form.Label>
<Form.Control
type="password"
name="password"
placeholder="Enter password"
onChange={getValue}
>
</Form.Control>
</Form.Group>
<Button
variant="primary"
type="submit"
>
Login
</Button>
</Form>
</Fragment>
)
}
const mapStateToProps = (state) => ({
isFetching: state.userReducer.isFetching,
isLoggedin: state.userReducer.isLoggedin,
isError: state.userReducer.isError,
errMessage: state.userReducer.errMessage
});
const mapDispatchToProps = dispatch => ({
userLogin: (userLogin) => {
dispatch(fetchLogin(userLogin))
}
});
export default connect(
mapStateToProps,
mapDispatchToProps
)(Login)
这里的问题是,当用户单击登录时,我执行的用于从后端登录用户的redux操作会花费一些时间,并且存储的更新速度不足以使userLogin函数确认用户是否已已登录。我知道这与Promise有关,但我不确定如何准确地做到这一点。
您可以在下面找到我的操作,唯一重要的操作是fetchLogin,这是从登录组件中分派的操作。
export const userLoginRequest = () => {
return {
type: USER_LOGIN_REQUEST,
payload: {
isFetching: true
}
};
}
export const userLoginSuccess = (user) => {
return {
type: USER_LOGIN_SUCCESS,
payload: {
user: {
...user
},
isLoggedin: true,
isFetching: false
}
};
}
export const userLoginFailed = () => {
return {
type: USER_LOGIN_FAILED,
payload: {
isFetching: false,
isError: true
}
};
}
export const fetchLogin = (userLogin) => dispatch => {
dispatch(userLoginRequest())
axios.post('/login', {
email: userLogin.email,
password: userLogin.password
})
.then(response => {
if (response.status === 200) {
dispatch(userLoginSuccess(response.data))
}
}, err => {
console.log("Error", err)
dispatch(userLoginFailed())
})
}
答案 0 :(得分:2)
您可以从操作中返回承诺,并在其解决后设置isLoggedin
的状态:
export const fetchLogin = (userLogin) => dispatch => {
dispatch(userLoginRequest())
return axios.post('/login', {
email: userLogin.email,
password: userLogin.password
})
.then(response => {
if (response.status === 200) {
dispatch(userLoginSuccess(response.data))
}
return response;
}).catch(err => {
console.log("Error", err)
dispatch(userLoginFailed())
})
}
// ...
const makeRequest = (e) => {
e.preventDefault()
props.userLogin(userLogin).then(resp => {
if (props.isLoggedin === true) {
console.log(Cookie.get('accessToken'))
props.history.push('/dashboard')
}
})
}
为此,您还需要更新mapDispatchToProps
才能真正返回调度:
const mapDispatchToProps = dispatch => ({
userLogin: (userLogin) => dispatch(fetchLogin(userLogin))
});
另一件事,我只是意识到在这种情况下使用分派的Promise进行正确重定向实际上是不必要的,因为可以在isLoggedin
中跟踪useEffect
道具
const makeRequest = (e) => {
e.preventDefault()
props.userLogin(userLogin)
}
useEffect(() => {
if (props.isLoggedin === true) {
console.log(Cookie.get('accessToken'))
props.history.push('/dashboard')
}
}, [props.isLoggedin])