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

Validate string length and make sure it contains certain characters in React Redux Form

正在开发一个 set_password.js 组件,您猜对了,它允许用户设置他们的密码。它让他们输入两次以确保它们匹配。密码的标准是至少8个字符,1个大写字母,1个数字,1个特殊字符。没什么突破性的。

我知道如何在服务器端验证这些东西,但宁愿在客户端验证它,这样用户就不必等待服务器响应。我正在为如何去做而苦恼。

我有一个 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>
            );
        } 
    }

现在,您的验证 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 的操作,以分别执行每个 null 检查。

https://regex101.com/ 是尝试正则表达式模式的好地方,如果您确实走那条路的话。

我 运行 遇到了一个类似的问题,即处理带有两个不同文本输入的表单提交,但用户可以选择向其中一个添加文本。我还发现有点令人沮丧的是,myString.length 之类的东西似乎可以工作 如果他们输入文本,但否则会破坏逻辑? 如果您可以添加库,

我要改变我的逻辑

if (myString.length == 0){
    //do stuff
 } 

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

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

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