传播运算符setState-React

时间:2019-06-23 15:58:50

标签: javascript reactjs

我处于这样的验证状态:

this.state = {
        email: '', pass: '',
        errors: {
            email: '', pass: ''
        }
    }

并且当用户按下按钮时,它会验证表单,如下所示:

    onSubmit = (e) => {
    e.preventDefault();

    this.setState({errors: {pass: '', email: ''}});

    const pass = this.state.pass.trim();

    if(!isEmail(this.state.email)){
        this.setState({errors: {...this.state.errors, email: 'Invalid Email.'}});
    }

    // return; - in this way email state error will be ok

    if(pass.length < 6){
        this.setState({errors:{ ...this.state.errors, pass: 'Password Invalid'}});
    }

    return console.log(this.state);
};

我正在使用...运算符在error对象中附加错误类型。问题是,如果电子邮件无效并且密码错误,则状态如下:

errors: {email: '', pass: 'Password Invalid'}

如果在通过检查之前使用return,则电子邮件错误状态正常。 我知道setState是异步的,但是如何附加不同的深度状态对象值?

2 个答案:

答案 0 :(得分:2)

完全创建错误对象之后,setState就可以了。您设置的状态超出了您的需要。一旦知道所有错误是什么,您才真正对在此功能中设置状态感兴趣。

onSubmit = (e) => {
    e.preventDefault();
    const pass = this.state.pass.trim();
    let errors = { pass: '', email: '' };
    if (!isEmail(this.state.email)) {
        errors.email = 'Invalid Email.';
    }
    if (pass.length < 6) {
        errors.pass = 'Password Invalid';
    }
    this.setState({ errors });
}

在这里使用...运算符不是问题。可能发生的事情是,React将您的更新捆绑在一起,因此每个更新都处于相同的状态。因此,如果您的状态为

{
    error: {
        email: '',
        pass: '',
    }
}

并且您有两个更新批处理在一起

setState({errors: {...this.state.errors, email: 'Invalid Email.'}});
setState({errors:{ ...this.state.errors, pass: 'Password Invalid'}});

它们都将看到相同的状态,并进行相应的更新以产生以下两个状态更新

this.state = {
    error: {
        email: 'Invalid Email',
        pass: '',
    }
};
this.state = {
    error: {
        email: '',
        pass: 'Password Invalid',
    }
};

其中第二个最有可能是您的结果,因为它是分配给该州的最后一个。

答案 1 :(得分:2)

使用状态功能,您可以做到:

this.setState(prevState => {
   const errors = {};

    if(!isEmail(prevState.email)){
        errors.email = 'Invalid Email.';
    }

    if(prevState.pass.trim().length < 6) {
        errors.pass = 'Password Invalid'
    }

    return {errors: {...prevState.errors, ...errors}}; // combine your new errors with another keys errors if exists
});