簡介
Formik 是為 React 開發的開源表單庫,提供狀態管理、驗證和提交處理功能,可簡化復雜表單的開發。
核心優勢
?- 狀態管理 ?:自動跟蹤輸入值、驗證狀態和提交進度,無需手動編寫狀態邏輯。 ?
?- 驗證功能 ?:支持聲明式驗證規則(如字段類型、長度限制、異步驗證),實時反饋錯誤信息。 ?
?- 集成能力 ?:可與 Yup (驗證)、 React Hook Form (表單鉤子)等庫組合使用,擴展功能。
安裝
npm install formik
示例
基本用法
import { useFormik } from "formik";export default function Formik() {const formik = useFormik({initialValues: {username: "",email: "",},validate: (values) => {const errors = {};if (!values.username) {errors.username = "用戶名是必填項";} else if (values.username.length < 2) {errors.username = "用戶名至少2個字符";}if (!values.email) {errors.email = "郵箱是必填項";} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)) {errors.email = "無效的郵箱地址";}return errors;},onSubmit: (values) => {console.log(values);alert(JSON.stringify(values, null, 2));},});return (<formonSubmit={formik.handleSubmit}className="max-w-sm mx-auto mt-10 p-6 border rounded shadow"><div className="mb-4"><label htmlFor="username" className="block mb-1 font-bold">用戶名</label><inputid="username"name="username"type="text"onChange={formik.handleChange}onBlur={formik.handleBlur}value={formik.values.username}className="w-full px-3 py-2 border rounded"/>{formik.touched.username && formik.errors.username ? (<div className="text-red-500 text-sm mt-1">{formik.errors.username}</div>) : null}</div><div className="mb-4"><label htmlFor="email" className="block mb-1 font-bold">郵箱</label><inputid="email"name="email"type="email"onChange={formik.handleChange}onBlur={formik.handleBlur}value={formik.values.email}className="w-full px-3 py-2 border rounded"/>{formik.touched.email && formik.errors.email ? (<div className="text-red-500 text-sm mt-1">{formik.errors.email}</div>) : null}</div><buttontype="submit"className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">提交</button></form>);
}
集成 yup
import { useFormik } from "formik";
import * as Yup from "yup";export default function Formik() {const formik = useFormik({initialValues: {username: "",email: "",},validationSchema: Yup.object({username: Yup.string().min(2, "用戶名至少2個字符").required("用戶名是必填項"),email: Yup.string().email("無效的郵箱地址").required("郵箱是必填項"),}),onSubmit: (values) => {alert(JSON.stringify(values, null, 2));},});return (<formonSubmit={formik.handleSubmit}className="max-w-sm mx-auto mt-10 p-6 border rounded shadow"><div className="mb-4"><label htmlFor="username" className="block mb-1 font-bold">用戶名</label><inputid="username"name="username"type="text"onChange={formik.handleChange}onBlur={formik.handleBlur}value={formik.values.username}className="w-full px-3 py-2 border rounded"/>{formik.touched.username && formik.errors.username ? (<div className="text-red-500 text-sm mt-1">{formik.errors.username}</div>) : null}</div><div className="mb-4"><label htmlFor="email" className="block mb-1 font-bold">郵箱</label><inputid="email"name="email"type="email"onChange={formik.handleChange}onBlur={formik.handleBlur}value={formik.values.email}className="w-full px-3 py-2 border rounded"/>{formik.touched.email && formik.errors.email ? (<div className="text-red-500 text-sm mt-1">{formik.errors.email}</div>) : null}</div><buttontype="submit"className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">提交</button></form>);
}
集成 react-hook-form
import { useForm } from "react-hook-form";export default function Formik() {const {register,handleSubmit,formState: { errors, touchedFields },} = useForm({mode: "onChange",defaultValues: {username: "",email: "",},});const onSubmit = (values) => {console.log(values);alert(JSON.stringify(values, null, 2));};return (<formonSubmit={handleSubmit(onSubmit)}className="max-w-sm mx-auto mt-10 p-6 border rounded shadow"><div className="mb-4"><label htmlFor="username" className="block mb-1 font-bold">用戶名</label><inputid="username"{...register("username", {required: "用戶名是必填項",minLength: { value: 2, message: "用戶名至少2個字符" },})}className="w-full px-3 py-2 border rounded"/>{touchedFields.username && errors.username && (<div className="text-red-500 text-sm mt-1">{errors.username.message}</div>)}</div><div className="mb-4"><label htmlFor="email" className="block mb-1 font-bold">郵箱</label><inputid="email"type="email"{...register("email", {required: "郵箱是必填項",pattern: {value: /^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i,message: "無效的郵箱地址",},})}className="w-full px-3 py-2 border rounded"/>{touchedFields.email && errors.email && (<div className="text-red-500 text-sm mt-1">{errors.email.message}</div>)}</div><buttontype="submit"className="bg-blue-500 text-white px-4 py-2 rounded hover:bg-blue-600">提交</button></form>);
}
formik validate、yup、react-hook-form 集成對比
1. Formik 自帶 validate
- 寫法:在 useFormik 里傳入 validate 函數,手動校驗每個字段,返回錯誤對象。
- 優點:
- 靈活,適合簡單或自定義復雜邏輯。
- 不依賴第三方庫。
- 缺點:
- 代碼冗長,重復性高。
- 維護性較差,規則多時易出錯。
- 示例:
validate: (values) => {const errors = {};if (!values.username) {errors.username = "用戶名是必填項";} else if (values.username.length < 2) {errors.username = "用戶名至少2個字符";}// ... 其他校驗return errors;};
2. Formik 集成 Yup
- 寫法:傳入 validationSchema,使用 Yup 對象聲明式定義規則。
- 優點:
- 規則聲明式,簡潔易讀。
- 支持復雜嵌套、異步校驗、類型校驗等。
- 維護性好,易擴展。
- 缺點:
- 需額外安裝 Yup。
- 某些極端自定義邏輯需配合 validate。
- 示例:
validationSchema: Yup.object({username: Yup.string().min(2, "用戶名至少2個字符").required("用戶名是必填項"),email: Yup.string().email("無效的郵箱地址").required("郵箱是必填項"),});
3. React Hook Form
- 寫法:通過 register 注冊字段時直接傳入校驗規則,也可結合 Yup。
- 優點:
- 語法簡潔,性能優異(按需渲染)。
- 支持原生表單校驗、異步校驗。
- 易與 Yup 等 schema 庫集成。
- 缺點:
- 語法與 Formik 不同,遷移需適應。
- 復雜表單時需結合第三方庫。
- 示例:
{...register("username", {required: "用戶名是必填項",minLength: { value: 2, message: "用戶名至少2個字符" },})}
總結對比表
特性 | Formik validate | Formik + Yup | React Hook Form |
---|---|---|---|
書寫方式 | 手寫函數 | 聲明式 schema | 注冊時傳規則 |
依賴 | 無 | Yup | 無/可選 Yup |
代碼量 | 多 | 少 | 少 |
維護性 | 一般 | 好 | 好 |
靈活性 | 高 | 高 | 高 |
性能 | 一般 | 一般 | 優 |
適合場景 | 簡單/自定義復雜邏輯 | 規則多/復雜表單 | 性能敏感/大表單 |
結論:
- 簡單表單可用 Formik 的 validate,復雜表單推薦 Yup 或 React Hook Form。
- 追求聲明式、可維護性優先用 Yup。
- 性能和體驗優先可選 React Hook Form。
?React 強大的表單驗證庫formik之集成Yup、React Hook Form庫 - 高質量源碼分享平臺-免費下載各類網站源碼與模板及前沿動態資訊