如何在React中异步删除错误消息

时间:2019-06-09 22:50:54

标签: reactjs redux

我正在提取一系列错误,其中一个错误说"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 个答案:

答案 0 :(得分:2)

您能从减速器的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
                )}