Я получаю массив ошибок, одна из которых говорит "Username is taken"
, а другая говорит "Password must be at least 5 chars"
.
Это отображается так в React.
{this.props.auth.errors ? (
this.props.auth.errors.map( (err, i) => (
<div key={i} style={{color: 'red'}}>
{err}
</div>
))
):(
null
)}
this.props.auth.errors
- это массив, содержащий сообщения об ошибках после вызова registerUser.
Actions.js
export const registerUser = (userData) => dispatch => {
Axios
.post('/users/register', userData)
.then( res => {
const token = res.data.token;
// console.log(token);
// pass the token in session
sessionStorage.setItem("jwtToken", token);
// set the auth token
setAuthToken(token);
// decode the auth token
const decoded = jwt_decode(token);
// pass the decoded token
dispatch(setCurrentUser(decoded))
// this.props.history.push("/dashboard")
}).catch( err => {
// console.log(err.response.data.error[0].msg)
Object.keys(err.response.data.error).forEach( (key) => {
dispatch({
type: GET_ERRORS,
payload: err.response.data.error[key].msg
})
})
})
};
Как бы я мог устранить ошибку, если, например, пользователь действительно вводит пароль, который составляет минимум 5 символов, или использует имя пользователя, которое существует? Если вы понимаете, о чем я ? Также это может быть сделано асинхронно? Как будто вы должны были войти в систему или зарегистрироваться на веб-сайте верхнего уровня в социальных сетях, где отображается ошибка в асинхронном режиме и сразу же после того, как вы выполнили сообщение об ошибке.
Полный код реакции
SignUp.js
import React, { Component } from "react";
import {connect} from 'react-redux';
import {registerUser} from '../actions/authActions';
import TextField from '@material-ui/core/TextField';
import Button from '@material-ui/core/Button';
import Grid from '@material-ui/core/Grid';
import PropTypes from "prop-types";
import Typography from '@material-ui/core/Typography';
class SignUp extends Component{
constructor() {
super();
this.state = {
formData:{
email:'',
username:'',
password:'',
passwordConf: "",
isAuthenticated: false,
},
errors:{},
passErr:null
}
}
componentDidMount() {
// console.log(this.props.auth);
if (this.props.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
}
// this line is magic, redirects to the dashboard after user signs up
componentWillReceiveProps(nextProps) {
if (nextProps.auth.isAuthenticated) {
this.props.history.push("/dashboard");
}
if (nextProps.errors) {
this.setState({ errors: nextProps.errors });
}
}
handleChange = (e) => {
e.preventDefault();
const {formData} = this.state;
this.setState({
formData: {
...formData,
[e.target.name]: e.target.value
}
});
}
handleSubmit = (e) => {
e.preventDefault();
const {formData} = this.state;
const {username, email, password, passwordConf} = formData;
this.setState({
username: this.state.username,
password: this.state.password,
passwordConf: this.state.passwordConf,
email: this.state.email
});
const creds = {
username,
email,
password
}
console.log(creds);
if (password === passwordConf) {
this.props.registerUser(creds, this.props.history);
} else {
this.setState({passErr: "Passwords Don't Match"})
}
}
render(){
return(
<div>
<Grid container justify="center" spacing={0}>
<Grid item sm={10} md={6} lg={4} style={{ margin:'20px 0px'}}>
<Typography variant="h4" style={{ letterSpacing: '2px'}} >
Sign Up
</Typography>
{this.props.auth.errors ? (
this.props.auth.errors.map( (err, i) => (
<div key={i} style={{color: 'red'}}>
{err}
</div>
))
):(
null
)}
{this.state.passErr && (
<div style={{color: 'red'}}>
{this.state.passErr}
</div>
)}
<form onSubmit={this.handleSubmit}>
<TextField
label="Username"
style={{width: '100%' }}
name="username"
value={this.state.username}
onChange={this.handleChange}
margin="normal"
/>
<br></br>
<TextField
label="Email"
className=""
style={{width: '100%' }}
name="email"
value={this.state.email}
onChange={this.handleChange}
margin="normal"
/>
<br></br>
<TextField
label="Password"
name="password"
type="password"
style={{width: '100%' }}
className=""
value={this.state.password}
onChange={this.handleChange}
margin="normal"
/>
<br></br>
<TextField
label="Confirm Password"
name="passwordConf"
type="password"
style={{width: '100%' }}
className=""
value={this.state.passwordConf}
onChange={this.handleChange}
margin="normal"
/>
<br></br>
<br></br>
<Button variant="outlined" color="primary" type="submit">
Sign Up
</Button>
</form>
</Grid>
</Grid>
</div>
)
}
}
SignUp.propTypes = {
registerUser: PropTypes.func.isRequired,
auth: PropTypes.object.isRequired,
};
const mapStateToProps = (state) => ({
auth: state.auth
})
const mapDispatchToProps = (dispatch) => ({
registerUser: (userData) => dispatch(registerUser(userData))
})
export default connect(mapStateToProps, mapDispatchToProps)(SignUp)
AuthReducer
import {SET_CURRENT_USER, GET_ERRORS} from '../actions/types';
import isEmpty from '../actions/utils/isEmpty';
const initialState = {
isAuthenticated: false,
errors: []
}
export default (state = initialState, action) => {
switch (action.type) {
case SET_CURRENT_USER:
return{
...state,
isAuthenticated: !isEmpty(action.payload),
user:action.payload
}
case GET_ERRORS:
console.log(action.payload)
// allows for us to loop through an array of errors.
return Object.assign({}, state, {
errors: [...state.errors, action.payload]
})
default:
return state;
}
}
пример пользовательского интерфейса, как это проигрывается