处理多个布尔状态变量进行验证



我正在React中构建一个表单,并具有验证用户提供的电子邮件和密码的功能:如果其中任何一个未通过验证,则状态变量将从true翻转为false,并有条件地呈现错误消息:

状态变量

const [isEmail, setEmail] = useState(true);
const [isPassword, setPassword] = useState(true);

验证功能

const validateEmailAndPassword = (email, password) => {
const emailRegEx =
/^(([^<>()[]\.,;:s@"]****************;
email.match(emailRegEx) ? setEmail(true) : setEmail(false);
password.length > 8 ? setPassword(true) : setPassword(false);
};

错误消息

<p className="errors">{!isEmail ? errors.email : null}</p>

与其单独声明每个状态变量,不如像我在表单中对其他输入所做的那样,用什么方法来更好地声明它们?

这是完整的文件:

import { useState, useEffect } from "react";
const Form = () => {
const [{ email, password,colour }, setFormDetails] = useState({
email: "",
password: "",
colour: ""
});
const [isEmail, setEmail] = useState(true);
const [isPassword, setPassword] = useState(true);
const [isTigerChecked, setTigerChecked] = useState(false);
useEffect(() => {
document.title = 'Contact form'
},[])

const errors = {
password: "Password needs to contain 8 or more characters",
email: "Please enter a valid email",
};
const handleChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
setFormDetails((prevForm) => ({
...prevForm,
[name]: value,
}));
};
const validateEmailAndPassword = (email, password) => {
const emailRegEx =
/^(([^<>()[]\.,;:s@"]+(.[^<>()[]\.,;:s@"]+)*)|(".+"))@(([[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}])|(([a-zA-Z-0-9]+.)+[a-zA-Z]{2,}))$/;
email.match(emailRegEx) ? setEmail(true) : setEmail(false);
password.length > 8 ? setPassword(true) : setPassword(false);
};

const handleClick = (e) => {
e.target.checked ? setTigerChecked(true) : setTigerChecked(false)
}
const handleSubmit = (e) => {
e.preventDefault();
validateEmailAndPassword(email, password);
};
return (
<div className="form-container">
<p>Contact form</p>
<form onSubmit={handleSubmit}>
<input
className="form-element"
type="text"
placeholder="Enter email address"
name="email"
onChange={handleChange}
/>
<p className="errors">{!isEmail ? errors.email : null}</p>
<input
className="form-element"
type="password"
placeholder="Enter password"
name="password"
onChange={handleChange}
/>
<p className="errors">{!isPassword ? errors.password : null}</p>
<fieldset className="form-element">
<legend>Please select a colour</legend>
<select name="colour" id="colour" onChange = {handleChange}>
<option value="Blue">Blue</option>
<option value="Green">Green</option>
<option value="Red">Red</option>
<option value="Black">Black</option>
<option value="Brown">Brown</option>
</select>
</fieldset>
<fieldset className="form-element">
<legend>Please select your animals</legend>
<div className="checkbox">
<input type="checkbox" id="bear" name="bear"  />
<label for="bear"> Bear</label>
<br></br>
<input
type="checkbox"
id="Tiger"
name="Tiger"
onClick={handleClick}
/>
<label for="Tiger"> Tiger</label>
<br></br>
<input type="checkbox" id="Snake" name="Snake" />
<label for="Snake"> Snake</label>
<br></br>
<input type="checkbox" id="Donkey" name="Donkey" />
<label for="Donkey"> Donkey</label>
<br></br>
</div>
</fieldset>
{isTigerChecked ? (
<textarea
id="tiger-type"
name="tiger-type"
rows="4"
cols="50"
placeholder="Please enter type of Tiger"
/>
) : null}
<button type="submit">Submit</button>
</form>
</div>
);
};
export default Form;

我会这样做:去掉isEmail和isPassword状态,创建一个以空对象为初始值的errors状态。

const [errors, setErrors] = useState({});

并将保存错误消息的errors obj的名称更改为errorMessages

const errorMessages = {
password: "Password needs to contain 8 or more characters",
email: "Please enter a valid email",
}

在验证函数中,将errorsObj变量分配给一个空对象。如果电子邮件不匹配,请更新errorsObj,以便将电子邮件密钥分配给来自errors对象的电子邮件错误字符串(与密码相同(。

const errorsObj = {};
if(!email.match(emailRegEx)) errorsObj['email'] = errors['email']
if (!(password.length > 8)) errorsObj['password'] = errors['password']
setErrors(errorsObj);

现在,当有条件地呈现错误消息时,执行这个

{!!errors['email'] && <p className="errors">{errors['email'}</p>}
{!!errors['password'] && <p className="errors">{errors['password'}</p>}

你也可以调整handleChange函数来正确更新错误

const handleChange = (e) => {
e.preventDefault();
const { name, value } = e.target;
setFormDetails((prevForm) => ({
...prevForm,
[name]: value,
}));
if (errors[name]) {
setErrors(prevState => {
delete prevState[name];
return prevState;
}
}
};

最新更新