反应中无法正确显示错误消息

时间:2020-07-04 15:21:31

标签: reactjs

我正在构建一个使用Django Rest Token身份验证的react登录页面。我正在登录页面中创建错误消息。但是我创建的错误之一无法正确显示。用户单击登录按钮(handleSubmit)后,应该显示该错误消息。但是,在用户另外输入了一个更改(handleChange )之后,该错误才会显示。我似乎无法跟踪代码中发生错误的位置。希望获得一些帮助。谢谢。

无法正确显示的错误是,它在下面的代码中,我将其包含在**中,以便您可以轻松识别它。 :-

{wrongcredentials ? <div className="errorMessage">Wrong username or password</div> : null}

下面是我的代码的核心部分:

const formValid = ({formErrors, ...rest})=> {
    let valid = true;
    Object.values(formErrors).forEach(val =>{
        val.length > 0 && (valid = false)
    });

    Object.values(rest).forEach(val =>{
        !(val) && (valid = false)
    });
    return valid;
}

let isloading = false;
let wrongcredentials = false;

class Login extends Component{
    constructor(props){
        super(props)
        this.state =  {
            credentials : {username :null, password  :null},
            formErrors :{
                username :'',
                password  :'',
            }
        };
    }

    handleSubmit = e => {
        e.preventDefault()
        if(formValid(this.state)){
            fetch('http://195.154.26.202:8000/auth/', {
                method: 'POST',
                headers: {'Content-Type': 'application/json'},
                body: JSON.stringify(this.state.credentials)
              }).then( data => data.json())
              .then(
                data => {
                    console.log('token', data.token)
                    if(data.token="undefined"){
                        console.error('wrong username or password')
                        wrongcredentials = true
                    }else{
                        window.location.href = '/';
                        isloading = true;
                    }
                    this.props.userLogin(data.token);
                }
              )
            console.log(`
            --SUBMITTING--
            username: ${this.state.credentials}
            password : ${this.state.credentials}
            `)
        }else{
            console.error('FORM INVALID')
        }
    }

    handleChange = e => {
        e.preventDefault()
        const cred = this.state.credentials;
        cred[e.target.name] = e.target.value;
        let formErrors = this.state.formErrors;

        switch(e.target.name){
            case 'username' :
                formErrors.username =  e.target.value.length>0 && e.target.value.length<3  ? 'minumum 3 characters required':
                    e.target.value.length==0? 'username is required': '';
            break;
            case 'password' :
                formErrors.password =  e.target.value.length>0 && e.target.value.length<6  ? 'minumum 6 characters required':
                    e.target.value.length==0? 'password is required': '';
            break;
            default:
                break;
        }
        this.setState({credentials: cred}, ()=> console.log(this.state))
    }

    render() {
        const {formErrors} = this.state
        console.log('wrong', wrongcredentials)
        return(
          <div className="Login">
            <div className="nav-bar">
                <div className="title-section">
                    <h6>lobstr.io</h6>
                </div>
            </div>
          <div className="wrapper">
          <form>
            <Heading>Sign In</Heading>
              <Input
                autoFocus
                type="text"
                className={formErrors.username.length>0? 'error': null}
                name="username"
                noValidate
                placeholder="username"
                onChange={this.handleChange}/>
                {formErrors.username.length>0 && (
                  <span className="errorMessage">{formErrors.username}</span>
                )}
              <Input
                name="password"
                placeholder="Password"
                onChange={this.handleChange}
                type="password"
                className={formErrors.password .length>0 ? 'error': null}/>
                {formErrors.password .length>0 && (
                  <span className="errorMessage">{formErrors.password}</span>
                )}
                <div className="additional">
              <FormGroup>
                    <FormCheck type="checkbox" value="remember" label="Remember me" />
                </FormGroup>

                <Link to ='/forgot-credentials'>Forgot credentials</Link>
                </div>
            <Button className="loginbtn" block bsSize="large" onClick={!isloading ? this.handleSubmit : null}>
            {isloading ? 'Loading…' : 'Sign in'}
            </Button>

    **{wrongcredentials ? <div className="errorMessage">Wrong username or password</div> : null}**

          </form>
              <Footer>
              <div className="company-login">
                  <p className="title-login">Pharmacy</p>
                  <h6 className="subtitle-login">Database Visualization</h6>
              </div>
            </Footer>
          </div>
        </div>
        )
    }
}

2 个答案:

答案 0 :(得分:2)

将可变凭证初始化为组件状态,并在出错时将其设置为true,然后将仅重新呈现 ...

constructor(props){
        super(props)
        this.state =  {
            credentials : {username :null, password  :null},
            formErrors :{
                username :'',
                password  :'',
            },
            wrongcredentials: false
        };
    }

...

...

.then(
                data => {
                    console.log('token', data.token)
                    if(data.token="undefined"){
                        console.error('wrong username or password')
                        this.setState({...this.state, wrongcredentials: true})
                    }else{
                        window.location.href = '/';
                        isloading = true;
                    }
                    this.props.userLogin(data.token);
                }
              )

...

答案 1 :(得分:0)

您将错误凭证指定为全局变量而非状态变量。发生的情况是:

  • 第一次错证=假

  • 如果用户第一次在输入字段中添加数据,不会出现
  • 问题,当用户单击“提交”按钮一次,然后单击该更改输入字段后,会显示错误消息,对吗?

  • 因为如果用户单击“提交”按钮并且令牌未定义,则您设置的错误凭证= true,但是由于未发生重新渲染,因此错误不会显示在屏幕上。 -此后,如果用户现在更改值,则错误的凭证值为true并发生重新渲染,因此问题显示在屏幕上

  • 为确保功能正常,请将错误的凭据设置为状态变量