简介
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 (
<form
onSubmit={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>
<input
id="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>
<input
id="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>
<button
type="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 (
<form
onSubmit={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>
<input
id="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>
<input
id="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>
<button
type="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 (
<form
onSubmit={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>
<input
id="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>
<input
id="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>
<button
type="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库 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯