React Hook Form 与 Formik 深度对比:如何为 React 表单管理选择最佳方案 📅 发布时间:2026/9/11 7:42:53 👁 浏览次数: React Hook Form 与 Formik 深度对比如何为 React 表单管理选择最佳方案【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine表单是 Web 应用收集用户数据的核心手段但在 React 这类前端框架中表单的创建、样式与校验往往并不轻松。幸运的是React Hook Form 与 Formik 两大开源库显著简化了这一过程。本文以二者为对比主体先分别介绍它们的基本用法、优点与短板再通过对照表、自定义校验、无障碍Accessibility实践三个维度展开深入对比最后结合本仓库refine中 React Hook Form 适配器的真实源码与示例说明当你在 CRUD 业务应用中需要“表单 数据交互”一体化能力时应如何做出选择并落地实践。阅读完本文你将掌握React Hook Form 与 Formik 的核心 API 与校验模型差异、二者在体积与维护状态上的客观差异以及如何编写自定义校验和无障碍表单并了解 Refine 如何通过refinedev/react-hook-form适配器将 React Hook Form 无缝嵌入数据管理应用。最流行的两个 React 表单库React 生态中存在多个可用于表单管理的包其中 React Hook Form 与 Formik 是最为流行的两个。本节将分别介绍它们的基本用法、优点与缺点。React Hook FormReact Hook Form 是一个用于在 React 及 Next、Gatsby 等 React 框架中管理表单的库。它是一个免费、开源的库采用 MIT 许可证因此几乎可以按任何方式使用。你可以使用它管理表单状态与字段校验也可以与 Material UI 等流行 UI 库集成。正如其名React Hook Form 基于 React Hooks 构建因此不能直接在 Class 组件中使用。React Hook Form 的基本用法在已有的 React 或 React Native 项目中通过以下任一命令安装# npm npm install react-hook-form # yarn yarn add react-hook-form下面的代码展示了一个使用useFormHook 的最基础登录表单。useForm是 React Hook Form 简化表单管理的关键 Hook几乎总是会用到它接收一个可选对象作为参数并返回多个方法。其中最重要的是register函数用于注册输入元素并应用校验规则第一个参数是唯一的输入名称字符串第二个可选参数用于添加校验字段如required、minLength。import { useForm } from react-hook-form; export function Form() { const { register, handleSubmit, watch, formState } useForm(); const submitHandler (data) console.log(data); return ( form onSubmit{handleSubmit(submitHandler)} p label htmlForusernameUsername/label input typetext idusername {...register(username, { required: true, minLength: 4 })} / /p p label htmlForPasswordPassword/label input typepassword idpassword {...register(password, { required: true, minLength: 10 })} required / /p button Submit /button /form ); }React Hook Form 的优点免费且开源。无依赖、体积小根据 bundlejs 的统计gzip 后体积约为 12.12KB。MIT 许可证。易于上手文档质量高。性能优秀。同时支持 React 与 React Native。开箱即用地校验表单字段。处于活跃维护状态社区活跃。可与 Material UI 等 UI 库集成也可以与 Refine 集成在 Refine 中可通过refinedev/react-hook-form适配器在 CRUD 应用中使用useFormHook 处理表单。React Hook Form 的缺点基于 React Hooks因此不能直接在 Class 组件中使用。FormikFormik 是一个免费、流行的开源包用于在 React 与 React Native 中构建表单。它内置了表单校验、错误消息与表单提交等管理能力API 表面较小即使是对 Formik 完全陌生的初学者也不难上手。Formik 的基本用法根据你使用的包管理器可通过以下任一命令在 React 或 React Native 项目中安装# npm npm install formik # yarn yarn add formik如果未使用 webpack 等打包器也可以通过 HTMLscript标签从 unpkg CDN 加载script srchttps://unpkg.com/formik/dist/formik.umd.production.min.js/script下面的代码展示了 Formik 构建登录表单的最基础用法。表单包含文本与 email 输入字段使用了内置的Form、Formik与Field组件Formik组件内部使用 render props可以向其传入 render prop 或用于包裹子组件除 render prop 外Formik组件还接受许多其他 props。Form是包裹 HTML form 元素的内置组件内部可以访问传给Formik的onSubmitprop 及其他 props。Field是向表单添加input元素的内置组件。import { Form, Formik, Field } from formik; export function LoginForm() { return ( h1Login form/h1 Formik initialValues{{ userName: , password: }} onSubmit{(values) console.log(values , values)} Form p label htmlForusernameUsername/label Field idusername required typetext nameuserName / /p p label htmlForpasswordPassword/label Field idpassword required typepassword namepassword / /p button typesubmitLogin/button /Form /Formik / ); }Formik 将表单校验交给开发者自己可以自行编写校验逻辑也可以使用 Yup 等第三方库。除基础用法外Formik 还提供了多种用于解决实际问题的复杂特性可查阅其官方文档。Formik 的优点同时支持 React 与 React Native。免费、性能良好。许可证灵活基于 Apache License 2.0 发布。轻量根据 bundlejs.com 的统计gzip 后体积约为 44.34KB。文档优秀易于上手。为 Ant Design、Material UI、Semantic UI 等流行 UI 框架提供了绑定。Formik 的缺点目前维护并不活跃截至撰写本文时其仓库最近一次 Git 提交已是一年之前同样至少一年没有发布新版本。Formik 与 React Hook Form 对比总览项目FormikReact Hook FormGzip 后打包体积44.34KB12.12KB依赖数量70活跃维护否是性能良好良好文档良好良好许可证Apache License 2.0MIT定价免费免费社区支持良好良好说明上表中的 GitHub Stars、NPM 周下载量、开放/关闭 Issue 数量等数据为原文档写作时的快照例如 Formik 约 31.6k Stars、NPM 周下载 2.1MReact Hook Form 约 32.2k Stars、周下载 2.7M。这些社区指标会随项目发展持续变化决策时应以最新数据为准而体积、依赖数与维护活跃度则是最稳定的参考维度。自定义校验两种实现路径自定义校验是表单开发中的高频需求。两个库都提供了清晰的实现方式但思路不同。React Hook Form通过 register 的 validate 规则React Hook Form 的自定义校验非常直接——在输入字段上通过register函数直接配置校验规则import { useForm } from react-hook-form; function MyForm() { const { register, handleSubmit, formState: { errors }, } useForm(); const onSubmit (data) { console.log(data); }; return ( form onSubmit{handleSubmit(onSubmit)} input {...register(username, { required: Username is required, validate: (value) value.length 4 || Username must be at least 4 characters, })} / {errors.username p{errors.username.message}/p} input {...register(email, { required: Email is required, pattern: { value: /^[a-zA-Z0-9_.-][a-zA-Z0-9-]\.[a-zA-Z0-9-.]$/, message: Invalid email address, }, })} / {errors.email p{errors.email.message}/p} button typesubmitSubmit/button /form ); }在上面的示例中我们为 username 与 email 字段设置了自定义校验消息。required可以直接携带字符串消息validate接收一个返回布尔值或字符串的函数返回字符串即错误消息正则校验则通过pattern的value与message配置。Formik通过 validate prop 集中校验Formik 同样支持自定义校验通过其validateprop 实现把校验逻辑写在一个函数中并传给Formikimport { Formik, Form, Field, ErrorMessage } from formik; function MyForm() { return ( Formik initialValues{{ username: , email: }} validate{(values) { const errors {}; if (!values.username) { errors.username Username is required; } else if (values.username.length 4) { errors.username Username must be at least 4 characters; } if (!values.email) { errors.email Email is required; } else if ( !/^[A-Z0-9._%-][A-Z0-9.-]\.[A-Z]{2,}$/i.test(values.email) ) { errors.email Invalid email address; } return errors; }} onSubmit{(values) { console.log(values); }} {({ handleSubmit }) ( Form onSubmit{handleSubmit} Field nameusername / ErrorMessage nameusername componentdiv / Field nameemail / ErrorMessage nameemail componentdiv / button typesubmitSubmit/button /Form )} /Formik ); }在这个例子中我们通过validate函数实现了 username 与 email 字段的自定义校验并使用内置的ErrorMessage组件渲染错误消息。两种方式各具特点React Hook Form 把校验规则内联在字段上粒度更细Formik 集中管理校验逻辑适合与 Yup 等 schema 校验库配合。无障碍Accessibility实践无障碍非常重要它确保我们的应用可以被包括残障人士在内的所有人使用。以下是借助 React Hook Form 与 Formik 提升表单无障碍性的指南与示例。React Hook Form 中的无障碍使用 React Hook Form 时应尽量使用语义化 HTML 元素并在必要时添加 ARIA 属性import { useForm } from react-hook-form; function AccessibleForm() { const { register, handleSubmit, formState: { errors }, } useForm(); const onSubmit (data) { console.log(data); }; return ( form onSubmit{handleSubmit(onSubmit)} div label htmlForusernameUsername/label input idusername aria-invalid{errors.username ? true : false} {...register(username, { required: Username is required })} / {errors.username span rolealert{errors.username.message}/span} /div div label htmlForemailEmail/label input idemail typeemail aria-invalid{errors.email ? true : false} {...register(email, { required: Email is required, pattern: { value: /^[a-zA-Z0-9_.-][a-zA-Z0-9-]\.[a-zA-Z0-9-.]$/, message: Invalid email address, }, })} / {errors.email span rolealert{errors.email.message}/span} /div button typesubmitSubmit/button /form ); }在这个示例中我们使用aria-invalid标记无效字段并使用rolealert让屏幕阅读器播报错误消息。Formik 中的无障碍Formik 同样支持无障碍增强通过正确使用语义化 HTML 元素与 ARIA 属性即可实现import { Formik, Form, Field, ErrorMessage } from formik; function AccessibleForm() { return ( Formik initialValues{{ username: , email: }} validate{(values) { const errors {}; if (!values.username) { errors.username Username is required; } if (!values.email) { errors.email Email is required; } else if ( !/^[A-Z0-9._%-][A-Z0-9.-]\.[A-Z]{2,}$/i.test(values.email) ) { errors.email Invalid email address; } return errors; }} onSubmit{(values) { console.log(values); }} {({ handleSubmit, errors, touched }) ( Form onSubmit{handleSubmit} div label htmlForusernameUsername/label Field idusername nameusername aria-invalid{ errors.username touched.username ? true : false } / ErrorMessage nameusername componentspan rolealert / /div div label htmlForemailEmail/label Field idemail nameemail typeemail aria-invalid{errors.email touched.email ? true : false} / ErrorMessage nameemail componentspan rolealert / /div button typesubmitSubmit/button /Form )} /Formik ); }在这个示例中我们确保所有表单字段都有正确的 label 与 ARIA 属性从而更易访问。注意 Formik 示例结合了touched状态来决定aria-invalid避免字段尚未被用户触碰时就过早标记为无效。实现这些无障碍特性会让我们的表单对用户更友好。在 Refine 中实战refinedev/react-hook-form 适配器如果你的表单需求不仅限于“收集与校验”还涉及数据资源的 CRUD 交互那么 Refine 官方提供的 React Hook Form 适配器会把这一过程变得非常顺滑。安装方式npm install refinedev/react-hook-form react-hook-form其最小用法如下package READMEimport { useForm } from refinedev/react-hook-form; const EditPost () { const { register, handleSubmit, formState, refineCore } useForm({ refineCoreProps: { resource: posts, id: 1, }, }); return; /* ... */ };适配器如何融合两套 useForm从源码看适配器的核心实现在 packages/react-hook-form/src/useForm/index.ts它同时调用 React Hook Form 自身的useHookForm与 Refine Core 的useFormCore将二者合而为一。返回类型UseFormReturnType是 React Hook Form 的UseFormReturn与 Refine Core 表单能力的交叉类型并额外提供refineCore透出 Refine Core 的表单能力onFinish、formLoading、query、onFinishAutoSave等负责数据加载与提交saveButtonProps包含disabled提交期间禁用与onClick的按钮属性内部会调用handleSubmit并触发onFinishhandleSubmit在 React Hook Form 原生handleSubmit之上包裹了一层先关闭“未保存更改”警告再提交。因此你既能享受 React Hook Form 的register/formState校验体验又能直接获得 Refine 的onFinish数据提交能力。查看 examples/form-react-hook-form-use-form/src/pages/posts/edit.tsx 中的编辑页示例可以看到典型的结合方式refineCore.onFinish直接作为handleSubmit的回调、saveButtonProps绑定到提交按钮useSelect加载关联分类数据并通过setValue回填category.id。配置项与服务器端校验UseFormProps在 React Hook Form 原生 props 基础上扩展了三个配置项见 packages/react-hook-form/src/useForm/index.tsrefineCoreProps传递给 Refine CoreuseForm的配置对象warnWhenUnsavedChanges存在未保存更改并试图离开页面时Refine 会弹出确认框默认关闭disableServerSideValidation是否禁用服务器端校验默认false。服务器端校验是适配器的一个亮点当onMutationError触发时见 packages/react-hook-form/src/useForm/index.ts适配器会遍历错误对象中的errors针对已注册到表单的字段调用setError写入错误消息错误值支持数组拼接为字符串、字符串、布尔值与带key/message的对象后者会通过 Refine 的translate进行 i18n 翻译。该行为在 useForm/index.spec.tsx 中有对应的测试用例模拟了title: [Title is required]、slug: true、content: { key: form.error.content, message: Content is required }等多种错误形态。更多场景Modal 表单与分步表单适配器还提供两个扩展 Hook均在useForm之上叠加能力useModalForm为表单附加modal对象submit、close、show(id?)、visible、title并支持modalProps配置defaultVisible、autoSubmitClose、autoResetForm、autoResetFormWhenClose默认分别为false、true、true、true还支持与 URL 同步的表单状态useStepsForm为表单附加steps对象currentStep、gotoStep支持stepsProps配置defaultStep默认 0与isBackValidate默认 false即返回上一步时是否校验当前步骤。仓库中的完整示例可参考 examples/form-react-hook-form-use-modal-form 与 examples/form-react-hook-form-use-steps-form。结论表单管理是 Web 开发中一个容易出错的领域尤其是在使用 React 这类前端框架时。HTML5 内置的表单功能在字段校验、错误管理与表单提交方面很有帮助而 Formik 与 React Hook Form 这类解决方案进一步简化了 React 及其框架中的表单管理。两者都是流行、免费、开源、成熟且经过大量实战检验的优秀包完全可以与原生 HTML5 表单功能配合使用。另一方面从 GitHub 上的提交与发布历史来看Formik 目前维护并不活跃——撰写本文时其仓库已有一年没有新的 Git 提交或版本发布。此外Formik 的打包体积相对更大gzip 后约 44.34KB而 React Hook Form 约为 12.12KBFormik 内部依赖 7 个包React Hook Form 则零依赖。综合双方优缺点如果你正准备在新项目中选择二者之一React Hook Form 是更稳妥的选择。而如果你的应用是基于 Refine 构建的 CRUD 系统refinedev/react-hook-form适配器还能把表单校验与数据交互无缝打通让 React Hook Form 的价值在真实业务场景中进一步放大。希望本文能帮助你为下一个项目做出合适的表单库决策。【免费下载链接】refineA React Framework for building internal tools, admin panels, dashboards B2B apps with unmatched flexibility.项目地址: https://gitcode.com/GitHub_Trending/re/refine创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考