как асинхронно удалять сообщения об ошибках в React - PullRequest
0 голосов
/ 10 июня 2019

Я получаю массив ошибок, одна из которых говорит "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;
    }
}

пример пользовательского интерфейса, как это проигрывается

enter image description here

enter image description here

1 Ответ

2 голосов
/ 10 июня 2019

Не могли бы вы очистить ошибки из вашего состояния в случае GET_ERRORS в вашем редукторе?В основном измените ваш случай GET_ERRORS следующим образом:

        case GET_ERRORS:
            console.log(action.payload)
            // allows for us to loop through an array of errors.
            return Object.assign({}, state, {
                errors: [action.payload]
            })     

Затем в вашем создателе действий сделайте это вместо этого:

         const errors = [];
         Object.keys(err.response.data.error).forEach( (key) => {
            errors.push(err.response.data.error[key].msg)
         })
         dispatch({
             type: GET_ERRORS,
             payload: errors,
         })   

Чтобы все ошибки в отдельных строках выполнялись примерно так:это в вашей функции рендеринга:

                {this.props.auth.errors ? (
                    this.props.auth.errors.map( (err, i) => (
                        <div key={i} style={{color: 'red'}}>
                            {err}

                        </div>
                        <br />
                    ))                  

                ):(
                    null
                )}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...