React 强大的表单验证库formik之集成Yup、React Hook Form库

简介

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 validateFormik + YupReact Hook Form
书写方式手写函数声明式 schema注册时传规则
依赖Yup无/可选 Yup
代码量
维护性一般
灵活性
性能一般一般
适合场景简单/自定义复杂逻辑规则多/复杂表单性能敏感/大表单

结论

  • 简单表单可用 Formik 的 validate,复杂表单推荐 Yup 或 React Hook Form。
  • 追求声明式、可维护性优先用 Yup。
  • 性能和体验优先可选 React Hook Form。

 React 强大的表单验证库formik之集成Yup、React Hook Form库 - 高质量源码分享平台-免费下载各类网站源码与模板及前沿动态资讯

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/news/913223.shtml
繁体地址,请注明出处:http://hk.pswp.cn/news/913223.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

破解风电运维“百模大战”困局,机械版ChatGPT诞生?

面对风机87%的非计划停机&#xff0c;30多个专用模型为何束手无策&#xff1f;一套通用大模型如何实现轴承、齿轮、转子“一站式”健康管理&#xff1f;一、行业痛点&#xff1a;风机运维深陷“碎片化泥潭”1.1 87%停机故障由多部件引发齿轮断裂、轴承磨损、电机短路……风电故…

Spring Bean 控制销毁顺序的方法总结

控制Spring Bean销毁顺序的方法 在Spring框架中&#xff0c;有几种方法可以控制Bean的销毁顺序。以下是主要的几种方式及其示例代码&#xff1a; 1. 实现DisposableBean接口 实现DisposableBean接口并重写destroy()方法&#xff0c;Spring会按照依赖关系的相反顺序调用这些方…

Gemini CLI MCP 教程:设置、命令与实际使用

如果你想要为任何 MCP 服务器设置 Gemini CLI,这个快速教程将为你提供指导。 Gemini CLI 结合 MCP(模型上下文协议)服务器,改变了你通过自然语言命令进行编码的方式。 你可以要求 Gemini 分析你的代码库、管理文件、查询数据库,或通过对话提示与 API 交互。 MCP 服务器连…

LangChain 构建向量数据库和检索器

LangChain 构建向量数据库和检索器实战 随着大语言模型&#xff08;LLM&#xff09;在各类 AI 应用中不断普及&#xff0c;RAG&#xff08;Retrieval-Augmented Generation&#xff0c;检索增强生成&#xff09;逐渐成为提升回答准确率与上下文关联性的重要技术路径。 一、什…

基于 LangChain 实现通义千问 + Tavily 搜索 Agent 的简单实践

文章目录 一、相关背景1.1 LangChain 简介1.2 通义千问&#xff08;Tongyi Qianwen&#xff09;1.3 Tavily 实时搜索引擎1.4 架构总览 二、环境配置设置 API 密钥 三、 Tavily 搜索四、智能 Agent 示例&#xff1a;自动判断是否调用 Tavily4.1 初始化 Agent4.2 提问两个问题&am…

SegGPT: 在上下文中分割一切

摘要 我们提出了 SegGPT&#xff0c;一个在上下文中执行“分割一切”的通用模型。我们将各种分割任务统一为一个通用的上下文学习框架&#xff0c;通过将不同类型的分割数据转换为相同的图像格式来兼容这些差异。SegGPT 的训练被建模为一个带有随机颜色映射的上下文着色问题。…

【网络】Linux 内核优化实战 - net.core.busy_read

目录 核心功能工作原理与优势配置方式1. 临时配置&#xff08;重启失效&#xff09;2. 永久配置&#xff08;重启生效&#xff09; 与 net.core.busy_poll 的协同作用适用场景与注意事项适用场景&#xff1a;注意事项&#xff1a; 总结 net.core.busy_read 是 Linux 内核中与网…

alpine安装及配置nodejs开发测试环境

在Alpine Linux上安装和使用Node.js&#xff0c;打造开发和测试的环境。 apk仓库打开社区的源。 先在命令行中使用命令apk search nodejs npm yarn对仓库源进行搜索&#xff0c;&#xff0c;看看nodejs、yarn、npm的版本情况。 localhost:~# apk search nodejs npm yarn nod…

Apache Commons Pool中的GenericObjectPool详解

GenericObjectPool 是 Apache Commons Pool 库中的核心类&#xff0c;用于实现对象的池化管理&#xff0c;适用于数据库连接、HTTP 客户端、线程等昂贵资源的复用。以下从核心概念、工作原理、参数配置、使用场景及最佳实践等方面详细解析&#xff1a; ⚙️ 一、核心概念与组成…

攻防世界CTF题目解析系列————(1)

题目来源:攻防世界wife_wife 打开题目之后&#xff0c;发现登录界面&#xff0c;然后尝试弱口令&#xff0c;sql二次注入&#xff0c;xss发现都没有&#xff0c;然后看见下面go register&#xff08;去注册&#xff09;按钮 成功注册&#xff08;username和password随便搞&…

楚存科技SD NAND贴片式T卡—高性能存储解决方案、赋能AI智能硬件

楚存科技SD NAND贴片式T卡—高性能存储解决方案、赋能AI智能硬件应用 在 AIoT 技术重构产业生态的时代浪潮中&#xff0c;智能硬件正从单一功能终端向数据枢纽演进 —— 智能家居设备日均产生 TB 级交互数据&#xff0c;工业物联网传感器需实时存储生产参数&#xff0c;车载智…

Python[数据结构及算法 --- 查找]

一.顺序查找&#xff08;无序表&#xff09;&#xff1a; def sequentialSearch(alist, item):pos 0found Falsewhile pos < len(alist) and not found:if alist[pos] item:found Trueelse:pos pos 1return foundtestlist [1, 2, 32, 8, 17, 19, 42, 13, 0] print(s…

Seata Saga模式实战:Java微服务中的分布式事务管理

在分布式系统中&#xff0c;Saga模式是一种用于管理跨多个服务的事务的柔性事务解决方案。它通过将长事务拆分为多个本地事务&#xff08;每个事务对应一个服务的操作&#xff09;&#xff0c;并通过补偿机制保证最终一致性。以下是Java中Saga模式的详细介绍&#xff0c;包括实…

若依学习笔记1-validated

<dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-web</artifactId></dependency><!-- 保证 Spring AOP 相关的依赖包 --><dependency><groupId>org.springframework.boot<…

Excel 如何处理更复杂的嵌套逻辑判断?

处理复杂的嵌套逻辑判断&#xff0c;是Excel进阶路上必然会遇到的一道坎。当简单的IF函数“套娃”变得冗长、难以阅读和维护时&#xff0c;我们就需要更高级、更清晰的工具。 这里介绍三种从基础到高级的处理方法&#xff1a; 传统的 IF 函数嵌套 (经典&#xff0c;但容易混乱)…

使用Claude和MCP增强Selenium

1.配置MCP服务器打开Claude Desktop—>Settings—>Developer—>Edit Config{"mcpServers": {"selenium": {"command": "npx","args": ["-y", "angiejones/mcp-selenium"]}} }配置完成后重启Cl…

数据仓库锚点建模方法的前世今生

数据仓库锚点建模方法&#xff08;Anchor Modeling&#xff09;作为一种面向复杂数据环境的创新方法论&#xff0c;其发展历程与技术演进深刻反映了数据管理从结构化到动态化的转型需求。以下从起源、发展、核心思想、技术演进及未来趋势五个维度&#xff0c;系统梳理锚点建模的…

<三>Sping-AI alibaba 文生图

环境和配置请看&#xff1c;二&#xff1e;Sping-AI alibaba 入门-记忆聊天及持久化 源代码&#xff1a;https://github.com/springaialibaba/spring-ai-alibaba-examples/blob/main/spring-ai-alibaba-image-example/dashscope-image/src/main/java/com/alibaba/cloud/ai/exam…

vue组件和模板

好的&#xff0c;我们来详细解释一下在 Vue&#xff08;以及现代前端开发&#xff09;中两个最核心的概念&#xff1a;组件 (Component) 和 模板 (Template)。 理解了它们&#xff0c;就等于掌握了现代 Web 应用开发的基石。 一个核心比喻&#xff1a;乐高积木 在开始前&…

python学习打卡:DAY 18 推断聚类后簇的类型

浙大疏锦行 聚类后的分析&#xff1a;推断簇的类型 知识点回顾&#xff1a; 推断簇含义的2个思路&#xff1a;先选特征和后选特征通过可视化图形借助ai定义簇的含义科研逻辑闭环:通过精度判断特征工程价值 作业&#xff1a;参考示例代码对心脏病数据集采取类似操作&#xff0c;…