我对React很陌生,并试图通过制作小型,简单的应用程序来学习。我正在制作一个具有React
功能的简单Login
应用程序。我也在使用Redux store
和Redux-saga
。我的登录流程是:
- 有一个
Login
组件,它从用户那里提取email
和password
,并在单击登录按钮时进行POST
调用。 -
email
和password
发送到服务器,如果它们有效,则服务器将在响应中返回一个令牌,并将其保存在local storage
中。 - 如果收到令牌,则将触发
Login success
的操作。在这里,我设置了一个名为success: true
的标志。 - 在前端,我检查
success
标志的值,如果是success==true
,则重定向到另一个名为Customers
的页面
登录组件
import React,{ Component } from 'react';
import { connect } from "react-redux";
import { withRouter } from 'react-router-dom';
import { loginRequest } from "../../actions/loginactions";
import './styles.css';
class Login extends Component {
constructor(props) {
super(props);
this.state = {
email: '',password: '',error: '',};
}
dismissError = () => {
this.setState({ error: '' });
}
handleSubmit = (evt) => {
evt.preventDefault();
let { email,password } = this.state;
if (!email) {
return this.setState({ error: 'username is required' });
}
if (!password) {
return this.setState({ error: 'Password is required' });
}
let data = {
email: email,password: password
}
this.props.login(data); //dispatches a method which then makes the POST call
//the checking happens before the above function has finished executing
if (this.props.success)
this.props.history.push('/customers');
else
return this.setState({
error: 'Invalid username/Password'
});
}
handleChange = (evt) => {
this.setState({
[evt.target.name]: evt.target.value
});
}
render() {
let { email,password } = this.state;
return (
<form classname="loginForm" onSubmit={this.handleSubmit}
action="/upload">
<h2>Login</h2>
{
this.state.error &&
<h3 classname='error' onClick={this.dismissError}>
<button onClick={this.dismissError}>✖</button>
{this.state.error}
</h3>
}
<label classname="FormFields label">Email</label>
<input type="email" classname="FormFields" name="email"
value={email}
onChange={(event) => this.handleChange(event)} />
<br />
<label classname="FormFields label">Password</label>
<input type="password" classname="FormFields" name="password"
value={password}
onChange={(event) => this.handleChange(event)} />
<br />
<input type="submit" classname="FormFields submit"
value="Login" />
</form>
);
}
}
const mapstatetoProps = (state) => {
return {
loading: state.login.loading,success: state.login.success
}
}
const mapDispatchToProps = (dispatch) => {
return { login: (data) => {dispatch(loginRequest(data))} }
}
export default withRouter(connect(mapstatetoProps,mapDispatchToProps)(Login));
登录传奇
import { put,takeEvery,call } from 'redux-saga/effects'
import { LOGIN_REQUEST,LOGIN_PENDING,LOGIN_SUCCESS,LOGIN_FAILURE } from '../actions/loginactions';
export function* login(action) {
const { data } = action.payload;
yield put({ type: LOGIN_PENDING })
let url = 'myserverurl/login'
try {
const response = yield call(fetch,url,{
method: 'POST',body: JSON.stringify(data),headers: {
'Content-Type': 'application/json',}
});
let tokenObj = yield response.json();
if (response.status === 200) {
localStorage.setItem('user',tokenObj.token);
yield put({ type: LOGIN_SUCCESS,token: tokenObj.token })
}
}
catch (error) {
yield put({ type: LOGIN_FAILURE,error })
}
}
export function* watchLogin() {
yield takeEvery(LOGIN_REQUEST,login)
}
登录还原器非常简单。
Login Reducer
import { LOGIN_REQUEST,LOGIN_FAILURE } from '../actions/loginactions';
const initState = {
loading: false,success: false,error: ''
}
const loginReducer = (state = initState,action) => {
switch (action.type) {
case LOGIN_REQUEST:
return {
...state,loading: false
}
case LOGIN_PENDING:
return {
...state,loading: true
}
case LOGIN_SUCCESS:
return {
...state,success: true,loading: false
}
case LOGIN_FAILURE:
return {
...state,loading: false,error: action.error
}
default: return state;
}
}
export default loginReducer;
登录组件中的语句this.props.login(data)
调度该操作,然后调用POST
。我想等待上面提到的整个流程完成,然后再检查成功标志的值,但这不会发生。
在登录的情况下,如何在我的前端检查success
标志之前等到我的登录减少器的操作完成?我阅读了async/await
上的文档,但是我不太了解如何正确使用它们。有人可以帮我吗