PA05▸🧩 Compose · 互動組合▸表單
Form Validation
表單驗證
難度 ★★★★★標籤 表單 · 驗證 · 狀態機3 min read
模式簡述
表單是「狀態機」最清楚的 UI:pristine → typing → error / valid → submitting → success。 每一步都要有對應的視覺。最常見的雷:未動過就標紅、submitting 中可重複 submit、success 後表單還能改。
Claude Code Prompt
參考:PA05 form-validation 技術:React 狀態 + 即時驗證 具體行為: - pristine(未動過):純背景,無錯誤 - typing:每 keystroke 即時驗證,錯誤即時顯示 - error:紅 border + 紅文字錯誤訊息 - submitting:按鈕 disabled + spinner - success:綠色 border + Check icon,按鈕 disabled 驗證規則: - Email: 必須包含 @ 跟 . 的合法格式 - Password: 至少 8 字元 限制: - pristine 絕對不顯示錯誤(使用者還沒輸入就被罵很不爽) - submitting 期間鎖按鈕,避免重複送出 - 錯誤訊息一定要具體(不要寫「格式錯誤」,寫「需包含 @」)
完整程式碼
'use client'
import { useState } from 'react'
type FormState = 'pristine' | 'typing' | 'error' | 'submitting' | 'success'
export function FormValidation() {
const [email, setEmail] = useState('')
const [password, setPassword] = useState('')
const [state, setState] = useState<FormState>('pristine')
const emailValid = /.+@.+\..+/.test(email)
const passwordValid = password.length >= 8
const showEmailError = state === 'typing' && email.length > 0 && !emailValid
const showPasswordError = state === 'typing' && password.length > 0 && !passwordValid
function handleSubmit() {
if (!emailValid || !passwordValid) {
setState('error')
return
}
setState('submitting')
setTimeout(() => setState('success'), 1200)
}
return (
<form onSubmit={e => { e.preventDefault(); handleSubmit() }}>
<input
value={email}
onChange={e => { setEmail(e.target.value); setState('typing') }}
className={showEmailError ? 'border-red-500' : 'border-border'}
/>
{showEmailError && <p className="text-red-500">Email 格式不正確</p>}
{/* ...password 同理... */}
<button disabled={state === 'submitting' || state === 'success'}>
{state === 'submitting' ? '送出中⋯' : state === 'success' ? '已送出' : '登入'}
</button>
</form>
)
}何時用
- ✅ 登入 / 註冊
- ✅ 結帳 / 訂單
- ✅ 任何需要明確「送出」動作的輸入
何時別用
- ❌ 搜尋框(即時查就好,不需要 submit)
- ❌ Autosave 表單(用 toast 提示,不用 submitting 狀態)
- ❌ 單一欄位的設定(用 input + blur 即可)
我踩過的坑
-
pristine 就標紅:使用者進到頁面看到一片紅,瞬間想關掉。 一定要等使用者動過才開始驗證。
-
submitting 期間沒鎖按鈕:使用者連點 3 下,後端收到 3 筆相同訂單。
disabled+ 換文案是基本盤。 -
錯誤訊息寫「格式錯誤」:使用者:「哪裡錯了?」要寫具體: 「Email 需包含 @」、「密碼至少 8 字元」。
相關模式
- 暫無