如何在用户键入或更改时验证表单的输入值?我正在尝试阅读state
,但这有点晚/不是实时的。
我正在考虑使用一个类变量/属性并对它进行突变,但是我担心它会冒犯React的原理。
是否有适当的方法在React中创建this之类的实时表单验证?
答案 0 :(得分:1)
验证是如此广泛地使用,以至于我们可以找到数十种有效的反应方式。我喜欢使用以下内容:
您不仅可以将输入的值保持为状态,还可以为每个对象创建一个更复杂的对象。让我们开始定义一个具有2个输入的表单:name
和age
。第一步将描述状态表单。像这样:
state = {
form:{
name:{
value : '',
valid : true,
rules:{
minLength : 3
}
},
age:{
value : '',
valid : true,
rules:{
isNumber : true
}
}
}
}
我们有它!现在,我们有2个在初始渲染上有效的输入,并具有自己的验证规则(isNumber,minLength)。现在我们需要编写一个函数来实时验证状态。然后让我们写它:
onChangeHandler = (key, value) =>{
this.setState(state =>({
...state,
form:{
...state.form,
[key]:{
...state.form[key],
value,
valid : validate(value, state.form[key].rules)
}
}
}))
}
现在,我们有了一个以状态描述的表单以及一个处理程序,该处理程序更新状态onChange
并验证每个调用的输入值。现在唯一要做的就是编写您的validate()
函数,您就可以开始了。
validate = (value, rules) => {
let valid = true
for (let key in rules) {
switch (key) {
case 'minLength':
valid = valid && minLengthValidator(value, rules[key])
break
case 'isNumber':
valid = valid && isNumberValidator(value)
break
default: break
}
}
return valid
}
现在验证器...
minLengthValidator = (value, rule) => (value.length >= rule)
isNumberValidator = value => !isNaN(parseFloat(value)) && isFinite(value)
完成!现在这样调用您的输入:
render(){
const { form } = this.state
return(
<TextField value={form.name.value} onChange={e => this.onChangeHandler('name',e.target.value)} />
)
}
每次输入更改验证功能时,都会触发一次,现在您具有实时表单验证,取决于您根据valid
道具应用各自的样式。
答案 1 :(得分:0)
我们必须定义一个validateProperty(input)并在我们的onChange方法中使用它。这是一个如何实现它的基本示例。首先定义您的状态。假设我有一个带有用户名和密码输入的表单。
state = {帐户:{用户名:“”,密码:“”},错误:{}};
validateProperty = (input) => {
if (input.name === "username") {
if (input.value.trim() === "") return "username is required";
}
if ((input.name = "password")) {
if (input.value.trim() === "") return "password is required";
}
};
现在我们必须在handleChange上使用它
e.currentTarget返回输入字段,我将其命名为输入并进行对象分解
handleChange = ({ currentTarget: input }) => {
const errors = { ...this.state.errors };
const errorMessage = this.validateProperty(input);
if (errorMessage) errors[input.name] = errorMessage;
else delete errors[input.name];
const account = { ...this.state.account };
account[input.name] = input.value; //currentTarget returns input field
this.setState(() => ({ account, errors }));
};
为每个输入字段添加“名称”属性。因此,如果name =“ username”用户名字段,如果name =“ password”密码字段,则errors [input.name]将是error [e.currentTarget.name]。