iT邦幫忙

2025 iThome 鐵人賽

DAY 23
0
Modern Web

30天入門:學會第一個前端框架-React系列 第 23

Day 23 | React入門:React 中驗證表單

  • 分享至 

  • xImage
  •  

表單驗證的應用

Day 21 | React入門:React 中的表單 ( Form )
的文章當中有提到:

表單是網站中,收集使用者資料的主要方式,例如我們常登入社群所需要的帳號密碼,甚至是貼文底下的留言,都是一種表單。

然而,如果某些必填或是格式錯誤的資料被送出之後,例如:

  • 註冊帳號的密碼太短
  • 電子郵件的格式不對
  • 留言區不能送出空白內容

這些資料不應該直接傳送到後端,否則會造成不必要的檢查與資源浪費。我們應該先在前端阻止表單送出,並清楚標示出錯誤的欄位與提示訊息,這時候就需要表單驗證的方法。

表單驗證的使用方式有很多,這裡我主要提供我在網路教學看到的一種方法:


表單驗證範例

1. 個別管理欄位

const [email, setEmail] = useState("");
const [message, setMessage] = useState("");

2. 錯誤訊息 & 送出狀態

const [formErrors, setFormErrors] = useState({});
const [isSubmit, setIsSubmit] = useState(false);

3. 表單送出

const handleSubmit = (e) => {
  e.preventDefault();
  const errors = validate({ email, message });
  setFormErrors(errors);
  setIsSubmit(true);
};

e.preventDefault():阻止表單的預設行為(避免頁面重新整理)
const errors = validate({ email, message }):呼叫驗證函式 ( validate ),將目前表單的輸入值帶入檢查,如果有欄位不符合規則,函式就會回傳一個錯誤訊息的物件
setFormErrors(errors):將 validate 回傳的錯誤訊息存入 formErrors 這個 state,讓畫面上顯示相對的錯誤提示
setIsSubmit(true);:設定表單嘗試送出,用於後續判斷是否顯示送出成功或錯誤訊息

4. 偵測錯誤變化

useEffect(() => {
  if (Object.keys(formErrors).length === 0 && isSubmit) {
    alert("送出成功");
  }
}, [formErrors, isSubmit]);

Object.keys(formErrors).length === 0 && isSubmit:判斷錯誤訊息物件是否為空,並確認表單已經嘗試送出。若兩者都成立,代表表單驗證通過,可以進行送出動作
[formErrors, isSubmit]:依賴陣列,只要其中一個的值有變化,useEffect 就會再次執行

5. 驗證邏輯

  const validate = (values) => {
  const errors = {};
  const regex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i;

  if (!values.email) {
    errors.email = "請輸入電子郵件";
  } else if (!regex.test(values.email)) {
    errors.email = "電子郵件格式不正確";
  }

  if (!values.message) {
    errors.message = "請輸入內容";
  } else if (values.message.length < 5) {
    errors.message = "內容至少需要 5 個字";
  }

  return errors;
};

const errors = {}:先建立一個空物件,用來暫存各個欄位可能的錯誤訊息
const regex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i:定義一個用來驗證 Email 格式的正則表達式,用來判斷使用者輸入的值是否為有效的電子郵件

完整範例程式碼

Contact.js

import { useState, useEffect } from "react";

export default function Contact() {
  const [email, setEmail] = useState("");
  const [message, setMessage] = useState("");

  const [formErrors, setFormErrors] = useState({});
  const [isSubmit, setIsSubmit] = useState(false);

  const handleSubmit = (e) => {
    e.preventDefault();
    const errors = validate({ email, message });
    setFormErrors(errors);
    setIsSubmit(true);
  };

  useEffect(() => {
    if (Object.keys(formErrors).length === 0 && isSubmit) {
      alert("送出成功");
    }
  }, [formErrors, isSubmit]);

  const validate = (values) => {
    const errors = {};
    const regex = /^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/i;

    if (!values.email) {
      errors.email = "請輸入電子郵件";
    } else if (!regex.test(values.email)) {
      errors.email = "電子郵件格式不正確";
    }

    if (!values.message) {
      errors.message = "請輸入內容";
    } else if (values.message.length < 5) {
      errors.message = "內容至少需要 5 個字";
    }

    return errors;
  };

  return (
    <div className="contact">
      <h3>聯絡我們</h3>

      {Object.keys(formErrors).length === 0 && isSubmit ? (
        <div className="ui message success">送出成功</div>
      ) : null}

      <form onSubmit={handleSubmit}>
        <label>
          <span>電子郵件:</span>
          <input
            type="text"
            name="email"
            value={email}
            placeholder="請輸入電子郵件"
            onChange={(e) => setEmail(e.target.value)}
          />
        </label>
        <p style={{ color: "red" }}>{formErrors.email}</p>

        <label>
          <span>內容:</span>
          <textarea
            name="message"
            value={message}
            placeholder="請輸入內容"
            onChange={(e) => setMessage(e.target.value)}
          ></textarea>
        </label>
        <p style={{ color: "red" }}>{formErrors.message}</p>

        <button>送出</button>
      </form>
    </div>
  );
}

瀏覽器執行畫面:錯誤訊息
https://i.meee.com.tw/6OiTFgd.gif

瀏覽器執行畫面:送出成功
https://i.meee.com.tw/QvdOqSP.gif


補充:更多驗證方法

  • 即時驗證 ( onChange ):例如輸入 Email 時,一旦格式錯誤,就立刻在欄位下方顯示紅字提醒,而不是等到點擊送出才檢查
  • 整合外部函式庫:像 Formik 或 React Hook Form,適合更大型或複雜的表單

總結

  • 表單驗證可以避免錯誤資料傳送到後端
  • 基本做法:收集資料 → 驗證 → 顯示錯誤或送出成功
  • 進階可以使用即時驗證或外部函式庫

上一篇
Day 22 | React入門:React 中送出表單資料
系列文
30天入門:學會第一個前端框架-React23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言