我在 React 中进行了一些表单验证,我可以在一个函数中使用状态中的一些全局变量来进行表单验证吗?有什么方法可以保持简单并仍然为每个输入提供不同的条件?出了点问题,我想要一些帮助,我不想包含电子邮件或任何内容的正则表达式模式..
注册.js
import React, { Component } from 'react'
export default class Registration extends Component {
state={
userName:'',
password:'',
email:'',
age:'',
backgroundColorInput:'white'
}
validLoginDetails=(item)=> {
locationOfS = email.indexOf('@');
this.setState({userName:item.target.value});
if(item.target.value.length>5 && item.target.value.length<9){
this.setState({backgroundColorInput:'green'})
}
this.setState({password:item.target.value});
if(item.target.value.length<7){
this.setState({backgroundColorInput:'red'})
}
this.setState({email:item.target.value});
if (item.target.value.locationOfS.indexOf(4) != -1) {
this.setState({backgroundColorInput:'green'} )
}
else{
this.setState({backgroundColorInput:'red'})
}
}
render() {
return (
<div>
<input placeholder='Enter your name' onChange={this.validLoginDetails} style={{backgroundColor: this.state.backgroundColorInput}} /><br/>
<input type='password' placeholder='Enter your a password' onChange={this.validLoginDetails} style={{backgroundColor: this.state.backgroundColorInput}} /><br/>
<input placeholder='Enter your Age' onChange={this.validLoginDetails} style={{backgroundColor: this.state.backgroundColorInput}} /><br/>
<input type="email" placeholder='Enter your Email' onChange={this.validLoginDetails} style={{backgroundColor: this.state.backgroundColorInput}} /><br/>
<button onClick={this.func}>submit</button>
</div>
)
}
}
应用程序.js
import React from 'react';
import './App.css';
import Registration from './components/Registration.js';
import Main from './components/Main.js';
function App() {
return (
<div className="App">
<Registration/>
<Main/>
</div>
);
}
export default App;
以下是我最近遇到的一些问题和解决方法,希望对你有帮助。
最近我想用 React 创建一个注册页面。我需要一个库来帮助我管理表单状态并验证表单值。然后我选择著名的“formik”+“Yup”。但经过一番尝试,我发现这并不能胜任工作。
formik 在任何字段值更改或模糊时验证每个字段。对于简单的验证来说,这不是一个大问题。但我需要通过网络检查用户名和电子邮件的可用性,这可能会花费很多时间。并且在检查时,会向用户呈现一个旋转。因此更改事件无法触发验证。另一方面,如果用户名已被检查且未更改,则不应再次检查。因为当用户不更改用户名字段时,他不会希望看到旋转。几乎所有的表单库都会在提交之前触发验证。但对于那些已经验证且尚未更改的字段,不应触发验证。 Formik很难达到以上要求
最后我开发了自己的库。它支持使用单独的触发器验证每个字段。 总的来说,有三个触发器:更改、模糊和提交。
对于更改,当字段值更改时,将进行验证。 对于模糊来说,情况会有点复杂。当模糊发生时,如果该字段已经有错误并且该字段自上次验证以来没有发生变化,则不应再次验证。如果字段没有错误,并且字段值自上次验证以来没有更改,则不应再次验证。如果该字段没有错误,但该字段自上次验证以来已发生更改,则应立即进行验证。 对于提交来说,与blur事件类似,当提交发生时,如果该字段已经有错误并且该字段值自上次验证以来没有发生变化,则不需要再次验证,并终止提交。如果该字段没有错误,并且该字段值自上次验证以来没有发生变化,则认为该字段已经过验证,不需要重新验证。如果字段没有错误并且字段值与上次验证相比已发生更改,则应重新启动验证任务。
有一个工作演示
这是代码示例
import React from 'react';
import { createValidator, useForm, OnSubmitFunction, REG_SPECIAL, string, sameWithWhenExists } from 'powerful-form-hook';
export const Demo = () => {
const initialValues = React.useMemo(() => ({
userName: '',
email: '',
password: '',
conformedPassword: '',
age: '',
}), []);
const validate = React.useMemo(() => createValidator<typeof initialValues>({
userName: (value) => {
if (!value) throw 'User name is required.'
if (value.length > 5 && value.length < 9) throw 'The length of user name should longer than 5 and shortter than 9.'
},
password: [
string()
.required('Password is required.')
.composedOf('Password must be composed of upper and lower case letters, Numbers and special keyboard symbols', /[a-z]+/i, /\d+/, REG_SPECIAL)
.matchSomeOf('The password must contain uppercase letters or special keyboard symbols', /[A-Z]+/, REG_SPECIAL)
.min(6, 'Password length must be greater than or equal to 6')
.max(24, 'Password length must be less than or equal to 24'),
// the validate task will trigger by blur of itself and conformedPassword field.
{
triggers: {
trigger: 'blur',
fields: ['conformedPassword'],
},
validate: sameWithWhenExists('conformedPassword', 'Enter the same password twice'),
},
],
conformedPassword: [
string('Password should be a string.'),
// the validate task will trigger by blur of itself and password field.
{
triggers: {
trigger: 'blur',
fields: ['password'],
},
validate: sameWithWhenExists('password', 'Enter the same password twice'),
},
],
age: string().matchSomeOf(/\d+/)
// same as userName.
email: [
string().required('Email is required.').trimmed('Email can not start or end with space.'),
],
}), []);
// Only when validate successful, the form submit. And if some validate task is running in the background or the form is submitting, the form will not be sumbited.
const onSubmit: OnSubmitFunction<typeof initialValues> = React.useCallback(async (values: typeof initialValues) => {
alert('submit successful');
}, []);
// handleChanges accept both event and value. For default, handleChanges will extract the value from event.target.value. For component like CheckBox which accept checked, use handleChanges[field].checked.
const { errors, values, handleChanges, handleBlurs, handleSubmit, submitting, validating } = useForm({
initialValues,
validate,
onSubmit,
});
return (
<form onSubmit={handleSubmit} noValidate>
<div>
<input placeholder='Enter your name' onChange={handleChanges.userName} onBlur={handleBlurs.userName} />
{ errors.userName.error ? errors.userName.message : null }
</div>
<div>
<input type='password' placeholder='Enter your a password' onChange={handleChanges.password} onBlur={handleBlurs.password} />
{ errors.password.error ? errors.password.message : null }
</div>
<div>
<input type='password' placeholder='Conform your a password' onChange={handleChanges.conformedPassword} onBlur={handleBlurs.conformedPassword} />
{ errors.conformedPassword.error ? errors.conformedPassword.message : null }
</div>
<div>
<input placeholder='Enter your Age' onChange={handleChanges.age} onBlur={handleBlurs.age} />
{ errors.age.error ? errors.age.message : null }
</div>
<div>
<input type="email" placeholder='Enter your Email' onChange={handleChanges.email} onBlur={handleBlurs.email} />
{ errors.email.error ? errors.email.message : null }
</div>
<button type="submit">submit</button>
{ submitting ? 'Submitting...' : validating ? 'Validating...' : null }
</form>
)
}