验证字符串长度并确保它包含React Redux表单中的某些字符

时间:2017-10-05 22:56:56

标签: javascript reactjs redux-form

使用set_password.js组件,您猜对了,让用户设置密码。它让他们输入两次以确保它们匹配。密码的条件是长度至少为8个字符,有一个大写,有一个数字,有一个特殊字符。什么都没有突破。

我知道如何验证这个东西服务器端,但宁愿验证它的客户端,所以用户不必等待服务器响应。我正在努力解决这个问题。

我有一个validate函数,它从字段中获取值并验证它们。

function validate(values) {
    const errors = {};

    if (!values.password1) {
        errors.password1 = 'This field cannot be empty.'
    }
    if (!values.password2) {
        errors.password2 = 'This field cannot be empty.'
    }
    if (values.password1.length < 8) {
         errors.password1 = 'The password provided is not long enough.'
    }
    if (values.password2.length < 8) {
         errors.password2 = 'The password provided is not long enough.'
    }
    return errors
}

到目前为止,这就是我所有的错误,我收到错误Cannot read property 'length' of undefined,所以我显然把这个逻辑放在了错误的区域。

我开始认为我应该把它放在动作中,所以只有在用户onSubmit之后才能验证它。我猜它看起来像是:

onSubmit(values) {
    this.props.setPassword(values, this.props.match.params);  
}
export function setPassword({ password1, password2 }, { id, key }) {
    return function(dispatch) {
        if (password1.length < 8 && password2.length < 8) {
            axios
                .post(
                    `${ROOT_URL}/api/auth/set_password/`, 
                    { password1, password2, id, key }
                )
                .then(response => {
                    console.log('Password changed')
                })
                .catch(error => {        
                    dispatch(authError(error.response.data.non_field_errors[0]));
        });
        }

    }
}

无论如何,那么实现这个目标的正确方法是什么?检查字符串的长度,它至少有一个大写字母,有一个特殊字符和一个数字?

编辑:

相关表格数据:

// This renders errors regarding the form inputs
    renderField(field) {
        const { 
            label, 
            type,
            name,
            meta: {
                touched, 
                error 
            } 
        } = field;

        return (
            <div className='form-group'>
                <label>{label}</label>
                <input 
                    className='form-control' 
                    type={type}
                    placeholder={label}
                    {...field.input} 
                />
                <div className='text-danger'>
                    {touched ? error : ""}
                </div>
            </div>
        );
    }

    // The main body to be rendered
    render() {
        if (this.props.permitRender) {
            const { handleSubmit } = this.props;
            return (
                <div>

                    <h3>Set New Password</h3>
                    <p>Type your new password twice. </p>
                    <p>It must be a minimum of 8 characters in length and contain at least:</p>
                    <ol>
                        <li>One uppercase character</li>
                        <li>One special character</li>
                        <li>One number</li>
                    </ol>

                    <form onSubmit={handleSubmit(this.onSubmit.bind(this))}>
                        {this.renderAlert()}
                        <Field 
                            label='Enter New Password'
                            name='password1'
                            type='password'
                            component={this.renderField} 
                        />
                        <Field 
                            label='Confirm New Password'
                            name='password2'
                            type='password'
                            component={this.renderField} 
                        />
                        <button type="submit" className="btn btn-primary">Submit</button>
                    </form>
                </div>
            );            
        } else if (!this.props.permitRender) {
            return ( 
                <div> { this.renderAlert() } </div>
            );
        } 
    }

2 个答案:

答案 0 :(得分:1)

现在,您的验证if - 语句的排序有些错误。我认为你不能假设任何密码值都设置了 最好先对要验证的字符串进行空值检查,然后再进行长度和字符检查。

可以通过使用一个(或更多,可能更容易)的正则表达式模式来验证字符应该在哪里。

// null check
if (!values.password1) {
    errors.password1 = 'This field cannot be empty.'
}
// After null checking, check length
else if (values.password1.length < 8) {
     errors.password1 = 'The password provided is not long enough.'
}
// Check for capital letters
else if (/([A-Z]+)/g.test(values.password1) {
     errors.password1 = 'You don\'t have any capital letters in there yo'
}

// Same here as before, pretty much
if (!values.password2) {
    errors.password2 = 'This field cannot be empty.'
}
else if (values.password2.length < 8) {
     errors.password2 = 'The password provided is not long enough.'
}

您还可以在if语句中执行values.password1 && values.password1.length > 8之类的操作,以单独执行每次空检查。

https://regex101.com/是一个尝试使用正则表达式进行试验的好地方。

答案 1 :(得分:0)

我在处理带有两个不同文本输入的表单提交时遇到了类似的问题,但是用户可以选择向一个或另一个添加文本。我还发现令人沮丧的是,如果myString.length这样的东西在输入文本的情况下似乎可以运行,但否则会破坏逻辑?如果您可以添加库,则

我将从

更改逻辑
if (myString.length == 0){
    //do stuff
 } 

转到LoDash _.isEmpty方法。看起来更像

if(_.isEmpty(myString)) {
   //do stuff...
  }

LoDash docs for isEmpty Method <-我一直在使用它,因为它适用于字符串,数组,对象等...希望对其他人有帮助!