React 的表單驗證篇總共會三篇,這篇我們會自己手刻一個驗證輸入值是否合法的表單,而在後面兩篇文章,我將會介紹使用 custom hook 及有名的第三方函式庫去實作表單驗證。
這篇文章不會注重 CSS 的樣式,有興趣的讀者在跟著步驟時可以自行加入。
const SimpleForm = () => {
return (
<form>
<label htmlFor="name">Your Name</label>
<input type="text" id="name" />
<label htmlFor="email">Your E-Mail</label>
<input type="email" id="email" />
<button>Submit</button>
</form>
);
};
const emailRule = /^\w+((-\w+)|(\.\w+))*\@[A-Za-z0-9]+((\.|-)[A-Za-z0-9]+)*\.[A-Za-z]+$/;
const SimpleForm = () => {
const [name, setName] = useState("");
const [nameTouched, setNameTouched] = useState(false);
const [email, setEmail] = useState("");
const [emailTouched, setEmailTouched] = useState(false);
const nameIsValid = name.trim() !== "";
const emailIsValid = emailRule.test(email);
const onChangeName = (e) => setName(e.target.value);
const onBlurName = () => setNameTouched(true);
const onChangeEmail = (e) => setEmail(e.target.value);
const onBlurEmail = () => setEmailTouched(true);
return (
<form>
<label htmlFor="name">Your Name</label>
<input
type="text"
id="name"
onChange={onChangeName}
onBlur={onBlurName}
value={name}
/>
<label htmlFor="email">Your E-Mail</label>
<input
type="email"
id="email"
onChange={onChangeEmail}
onBlur={onBlurEmail}
value={email}
/>
<button>Submit</button>
</form>
);
};
const SimpleForm = () => {
const [name, setName] = useState("");
const [nameTouched, setNameTouched] = useState(false);
const [email, setEmail] = useState("");
const [emailTouched, setEmailTouched] = useState(false);
const nameIsValid = name.trim() !== "";
const emailIsValid = emailRule.test(email);
const onChangeName = (e) => setName(e.target.value);
const onBlurName = () => setNameTouched(true);
const onChangeEmail = (e) => setEmail(e.target.value);
const onBlurEmail = () => setEmailTouched(true);
const onFormSubmit = (e) => {
e.preventDefault();
if (!nameIsValid) setNameTouched(true);
if (!emailIsValid) setEmailTouched(true);
if (!nameIsValid || !emailIsValid) return;
console.log("submit success!");
console.log(name, email);
// reset
setName("");
setNameTouched(false);
setEmail("");
setEmailTouched(false);
};
return (
<form onSubmit={onFormSubmit}>
<label htmlFor="name">Your Name</label>
<input
type="text"
id="name"
onChange={onChangeName}
onBlur={onBlurName}
value={name}
/>
<label htmlFor="email">Your E-Mail</label>
<input
type="email"
id="email"
onChange={onChangeEmail}
onBlur={onBlurEmail}
value={email}
/>
<button disabled={!nameIsValid || !emailIsValid}>Submit</button>
</form>
);
};
先加上一小段 CSS
.invalid {
border: 1px solid red;
}
.error-text {
color: red;
}
主程式的部分
const SimpleForm = () => {
const [name, setName] = useState("");
const [nameTouched, setNameTouched] = useState(false);
const [email, setEmail] = useState("");
const [emailTouched, setEmailTouched] = useState(false);
const nameIsValid = name.trim() !== "";
const emailIsValid = emailRule.test(email);
const onChangeName = (e) => setName(e.target.value);
const onBlurName = () => setNameTouched(true);
const onChangeEmail = (e) => setEmail(e.target.value);
const onBlurEmail = () => setEmailTouched(true);
const onFormSubmit = (e) => {
e.preventDefault();
if (!nameIsValid) setNameTouched(true);
if (!emailIsValid) setEmailTouched(true);
if (!nameIsValid || !emailIsValid) return;
console.log("submit success!");
console.log(name, email);
// reset
setName("");
setNameTouched(false);
setEmail("");
setEmailTouched(false);
};
const nameInputClasses = !nameIsValid && nameTouched ? "invalid" : "";
const emailInputClasses = !emailIsValid && emailTouched ? "invalid" : "";
return (
<form onSubmit={onFormSubmit}>
<label htmlFor="name">Your Name</label>
<input
type="text"
id="name"
onChange={onChangeName}
onBlur={onBlurName}
value={name}
className={nameInputClasses}
/>
{!nameIsValid && nameTouched && (
<p className="error-text">Name must not be empty.</p>
)}
<label htmlFor="email">Your E-Mail</label>
<input
type="email"
id="email"
onChange={onChangeEmail}
onBlur={onBlurEmail}
value={email}
className={emailInputClasses}
/>
{!emailIsValid && emailTouched && (
<p className="error-text">Please enter a valid email.</p>
)}
<button disabled={!nameIsValid || !emailIsValid}>Submit</button>
</form>
);
};
透過以上步驟,就可以建立出簡單的表單驗證,有錯誤的提示文字外也有輸入框邊框變紅色的警告提示,不過當表格要填入的欄位變多就會變得複雜。
因此下一篇將用 custom hook 去進行表單驗證,將一些欄位輸入的相關邏輯抽取出來。