React七Formik

Formik是一个专为React构建的开源表单库。它提供了一个易于使用的API来处理表单状态管理,表单验证以及表单提交。Formik支持React中的所有表单元素和事件,可以很好地与React生态系统中的其他库集成。同时,Formik还提供了一些高级功能,如支持异步验证、字段级别的验证、根据表单状态变化自动计算属性等。

Formik 基础

Formik的优势,相较于传统的表单处理方法,Formik具有以下优势:

  • 状态管理: Formik自动地处理表单状态管理,无需手动编写大量的状态管理逻辑。
  • 表单验证: Formik提供了易于使用的表单验证工具,可以快速实现表单验证逻辑。
  • 表单提交: Formik可以方便地处理表单提交,包括异步表单提交和重试机制。
  • 支持复杂表单: Formik支持处理包括多级嵌套、动态表单、数组表单等多种复杂表单。

Formik 安装和简单使用

1、Formik安装,使用npm或yarn安装Formik。在终端中,切换项目目录并运行此命令 npm install formikyarn add formik

2、表单数据绑定以及提交处理

useFormik HOOK 参数说明:

  • initialValues:传递定义的输入HTML元素的name属性相匹配的初始值
  • onSubmit:提交程序,已经默认阻止了默认行为

onSubmit 属性定义了一个回调函数,在表单提交时被调用。在回调函数中可以访问表单中所有输入框的值并执行提交操作,通过 setSubmitting 函数,可以设置表单的提交状态。在表单的渲染函数中通过 handleSubmit 属性来处理表单的提交,使用 isSubmitting(默认false) 属性来禁用提交按钮,直到表单提交完成。

        const formik = useFormik({initialValues: {username: '',password: ''},onSubmit: (values, {setSubmitting}) => {// formik 已经默认帮我们阻止了默认执行console.log('values: ', values);setSubmitting(true)}})……<form onSubmit={formik.handleSubmit}><div><label htmlFor="username">用户名:</label><input id="username" type="text" name="username" value={formik.values.username} onChange={formik.handleChange}></input></div><div><label htmlFor="password">密码:</label><input id="password" type="password" name="password" value={formik.values.password} onChange={formik.handleChange}></input></div><button type="submit" disabled={formik.isSubmitting}>提交</button></form>

useFormik 返回对象属性解释:

  • handleSubmit:提交处理程序
  • handleChange:传递给每个<input><select>、 或<textarea>的更改处理程序
  • values:表单的当前值,使用 name 访问对应的值
  • handleChange:每个 HTML 输入重用相同的更改处理函数
  • setValues和setFieldValue:setValues设置formik的values属性值,setFieldValue设置values的某一个属性值,二者写法不同,但是目的一样改变values的值。

如果没有 formik,那么就得一个个写change事件。

3、表单校验

Formik 不仅跟踪表单values,还跟踪其验证和错误消息。要使用 JS 添加验证,需指定一个自定义验证函数并将其传递给钩子 useFormik() 的参数 validate。如果存在错误,这个自定义验证函数应该生成一个匹配的error对象。

            validate: values => {const errors = {}if (!values.username) {errors.username = '请输入用户名'} else if (values.username.length < 6 || values.username.length > 16) {errors.username = '请输入6~16位的用户名'} else if (!/^\w{6,16}$/.test(values.username)) {errors.username = '请输入由字母、数字、下划线组成的用户名'}if (!values.password) {errors.password = '请输入密码'} else if (values.password.length < 6 || values.password.length > 16) {errors.password = '请输入6~16位的密码'} else if (!/^\w{6,16}$/.test(values.password)) {errors.password = '请输入由字母、数字、下划线组成的密码'}console.log('errors: ', errors);return errors}

默认情况下,Formik 将在每次击键(onChange)事件以及提交之前进行验证。传递 formik.handleBlur 给输入元素的 onBlur 属性,那么会在输入元素的失焦(onBlur)事件中进行验证:

    <input id="username" type="text" name="username" value={formik.values.username} onChange={formik.handleChange} onBlur={formik.handleBlur}></input>

校验确实实现了,但是如果希望在提交表单的时候再显示错误,需要怎么做呢?
Formik 会跟踪哪些字段已被访问过。它将这些信息存储在一个名为 touched 的对象中,这些值为boolean值。

        <p>{formik.touched.username && formik.errors.username ? formik.errors.username : ''}</p>

Formik 结合 Yup 进行表单验证

Yup是一个构建对象模式的JavaScript模式验证器,用于验证和解析数据。它提供了一种声明式方法来创建校验模式。

由于 Formik 作者/用户非常喜欢Yup,因此 Formik 有一个名为 Yup 的特殊配置道具validationSchema,它会自动将 Yup 的验证错误消息转换为一对象。

1、Yup 安装 npm install yupyarn add yup

2、使用 Yup 校验表单:

  • Formik 结合 Yup 可以轻松实现表单验证 validationSchema={Yup.object({...})},使用 validationSchema 和 Yup 搭配之后就不需要再使用validate配置了。
  • Yup 允许创建复杂的校验逻辑,如必填项、字符长度、正则表达式等。
            validationSchema: Yup.object({username: Yup.string().required('请输入用户名').min(6, '请输入6~16位的用户名').max(16, '请输入6~16位的用户名').matches(/^\w{6,16}$/, '请输入由字母、数字、下划线组成的用户名'), password: Yup.string().required('请输入密码').min(6, '请输入6~16位的密码').max(16, '请输入6~16位的密码').matches(/^\w{6,16}$/, '请输入由字母、数字、下划线组成的密码')})

Formik 组件

以上都是通过 useFormik 拿到控制formik表单的内容,但是这样不容易形成封装,也就是说无法进行实例传值。而Formik由于配备了React Context,因此Formik本身就可以管理所包裹的JSX。

formik完全遵守React的组件化原则,可以和其他库或自定义逻辑无缝集成:

  • formik支持构建和复用表单组件,通过<Formik />组件和Context API实现跨组件通信。
  • 可以创建包装<Field />ErrorMessage等的自定义组件,提高代码复用性和可维护性。
            <Formik initialValues={{username: '', password: ''}} // 设置初始化值onSubmit={(values, {setSubmitting}) => { // 提交表单执行的函数setTimeout(() => {console.log('values: ', values); setSubmitting(true)}, 2000);}}validationSchema={Yup.object({ // 设置表单校验的模式username: Yup.string().required('请输入用户名').min(6, '请输入6~16位的用户名').max(16, '请输入6~16位的用户名').matches(/^\w{6,16}$/, '请输入由字母、数字、下划线组成的用户名'), password: Yup.string().required('请输入密码').min(6, '请输入6~16位的密码').max(16, '请输入6~16位的密码').matches(/^\w{6,16}$/, '请输入由字母、数字、下划线组成的密码')})}>{({handleSubmit, values, touched, handleChange, handleBlur, errors, isSubmitting}) => {return <form onSubmit={handleSubmit}><div><label htmlFor="username1">用户名:</label>{/* <input id="username1" type="text" name="username" value={values.username} onChange={handleChange} onBlur={handleBlur}></input> */}<Field id='username1' name='username' type='text'></Field>{/* <p>{touched.username && errors.username ? errors.username : ''}</p> */}<ErrorMessage name="username"></ErrorMessage></div><div><label htmlFor="password1">密码:</label><input id="password1" type="password" name="password" value={values.password} onChange={handleChange}></input><p>{touched.password && errors.password ? errors.password : ''}</p></div><button type="submit" disabled={isSubmitting}>提交</button></form>}}</Formik>
常用组件

1、ErrorMessage 捕捉错误的容器,必传一个name属性。

    <ErrorMessage name="username"></ErrorMessage>

2、Field 将自动将输入连接到 Formik,默认渲染是input输入框,有以下几种方法渲染:

    function MyField({field, form}) {console.log('field: ', field);console.log('form: ', form);return <input {...field}></input>}……<Formik initialValues={{email: '', project: 2, phone: '', address: '1'}} // 设置初始化值onSubmit={(values) => { console.log('values: ', values); }} // 提交表单执行的函数validationSchema={Yup.object({ // 设置表单校验的模式phone: Yup.string().required('请输入电话号码').matches(/^1[0-9]{10}/, '请输入有效的电话号码')})}>{({handleSubmit}) => {return <form onSubmit={handleSubmit}>{/* 1、直接渲染 */}<Field type='email' name='email' placeholder='请输入电子邮箱'></Field> <br/>{/* 2、as 转化成其他节点 */}<Field as='select' name='project'><option value={1}>数学及应用数学</option><option value={2}>软件工程</option><option value={3}>国际贸易</option></Field> <br/>{/* 3、渲染 jsx */}<Field name='phone'>{({field, form, meta}) => {console.log('field: ', field);console.log('form: ', form);console.log('meta: ', meta);return <div><label htmlFor="phone">电话号码</label><input id="phone" type="text" placeholder="请输入电话号码" value={field.value.phone} {...field}></input><p>{ meta.touched && meta.error ? meta.error : ''}</p></div>}}</Field>{/* 4、以 component 组件形式渲染 */}<Field name='address' component={MyField}></Field> <br /><button type="submit">提交</button></form>}}</Formik>

数组和对象校验

Formik 支持嵌套对象和数组:

  • yup 对象校验使用 Yup.object({})
  • yup 数组校验使用 Yup.array().of()
        <FormikinitialValues={{social: {wechat: '', qq: ''}, frends: ['', '']}}onSubmit={(values, {setSubmitting}) => {console.log('values: ', values)setSubmitting(true)}} validationSchema={Yup.object({social: Yup.object({wechat: Yup.string().required('请输入微信'), qq: Yup.string().required('请输入QQ').matches(/^[\w]$/, '请输入有效的QQ')}),frends: Yup.array().of(Yup.string().required('请输入你的朋友'))})}>{({values, handleChange, handleBlur, touched, errors, isSubmitting, setValues, setFieldValue}) => {console.log('object array values: ', values);console.log('object array handleChange: ', handleChange);console.log('object array handleBlur: ', handleBlur);console.log('object array touched: ', touched);console.log('object array errors: ', errors);console.log('object array setValues: ', setValues);console.log('object array setFieldValue: ', setFieldValue);return <form><h4>社交账号</h4><label>微信:</label><input name="social.wechat" value={values.social.wechat} onChange={handleChange} onBlur={handleBlur}></input><p>{ touched.social && errors.social && touched.social.wechat && errors.social.wechat ? errors.social.wechat : ''}</p><br /><label>QQ:</label><input name="social.qq" value={values.social.qq} onChange={handleChange} onBlur={handleBlur}></input><h4>朋友</h4>{values.frends.map((v, i) => {return (<div key={i}><input name={`friends[${i}]`} onChange={handleChange} onBlur={handleBlur}></input>{i < values.frends.length && <br />}</div>)})}<button type="submit" disabled={isSubmitting}>提交</button></form>}}</Formik>

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

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

相关文章

【Kimi】自动生成PPT-并支持下载和在线编辑--全部免费

【Kimi】免费生成PPT并免费下载 用了好几个大模型&#xff0c;有些能生成PPT内容&#xff1b; 有些能生成PPT&#xff0c;但下载需要付费&#xff1b; 目前只有Kimi生成的PPT&#xff0c;能选择模板、能在线编辑、能下载&#xff0c;关键全部免费&#xff01; 一、用kimi生成PP…

编写一个程序,计算并输出1到100的和(Python版)

编写一个程序&#xff0c;计算并输出1到100的和 以下是两种计算1到100之和的方法&#xff1a; 方法一&#xff1a;循环累加法&#xff08;适合编程练习&#xff09; total 0 for num in range(1, 101):total num print("1到100的和为:", total)原理&#xff1a;通…

MyBatis-Plus 自动填充功能

MyBatis-Plus&#xff08;MP&#xff09; 提供了一个非常强大的功能——自动填充功能。该功能可以在执行插入或更新操作时&#xff0c;自动为某些字段赋值&#xff0c;免去手动设置这些字段的麻烦。常见的应用场景包括 创建时间 和 更新时间 字段的自动填充&#xff0c;帮助开发…

final 关键字在不同上下文中的用法及其名称

1. final 变量 名称&#xff1a;final 变量&#xff08;常量&#xff09;。 作用&#xff1a;一旦赋值后&#xff0c;值不能被修改。 分类&#xff1a; final 实例变量&#xff1a;必须在声明时或构造函数中初始化。 final 静态变量&#xff1a;必须在声明时或静态代码块中初…

springboot项目部署脚本

Springboot部署脚本 该脚本可用于jenkins自动执行&#xff0c;具有以下功能 适配所有以内嵌tomcat容器springboot项目jar包可根据参数选择环境&#xff0c;基于profiles可自动识别并关闭已存在进程第一个参数是指定jar包所在绝对路径(该路径下必须有且仅有一个.jar文件) 第二…

向量数据库milvus部署

官方文档 Milvus vector database documentationRun Milvus in Docker (Linux) | Milvus DocumentationMilvus vector database documentation 按部署比较简单&#xff0c;这里说一下遇到的问题 一&#xff1a;Docker Compose 方式部署 1、镜像无法拉取,(docker.io被禁) …

【密码学实战】Java 实现 SM2 国密算法(签名带id、验签及 C1C3C2 加密解密)

前言 SM2是中国国家密码管理局发布的椭圆曲线公钥密码算法标准&#xff08;GB/T 32918&#xff09;&#xff0c;属于国密算法体系。与RSA和ECDSA相比&#xff0c;SM2在相同安全强度下密钥更短、计算效率更高。本文将介绍如何在Java中实现SM2的密钥生成、数字签名、验签、加密及…

网络原理---TCP/IP

活动发起人小虚竹 想对你说&#xff1a; 这是一个以写作博客为目的的创作活动&#xff0c;旨在鼓励大学生博主们挖掘自己的创作潜能&#xff0c;展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴&#xff0c;那么&#xff0c;快来参加吧&#xff01…

【大语言模型笔记进阶一步】提示语设计学习笔记,跳出框架思维,自己构建提示词

一、大语言模型应用场景 1. 文本生成 文本创作&#xff1a; 诗歌故事&#xff0c;剧本&#xff0c;推文帖子 摘要与改写&#xff1a; 长文本摘要与简化&#xff0c;多语言翻译与本地化 结构化生成&#xff1a; 表格&#xff0c;根据需求生成代码片段&#xff0c;API文档生成…

Unity XR-XR Interaction Toolkit开发使用方法(十一)组件介绍(XR Interactable)

目录 一、插件介绍 二、主要组件 XR Interaction Manager XR Controller XR Interactor XR Direct Interactor XR Ray Interactor XR Socket Interactor XR Gaze Interactor XR Interaction Group 三、XR Interactable 1、组件介绍 2、核心功能与特点 交互类型支…

Spring Boot spring-boot-maven-plugin 参数配置详解

一 spring-boot-maven-plugin 插件的5个Goals spring-boot:repackage&#xff0c;默认goal。在mvn package之后&#xff0c;再次打包可执行的jar/war&#xff0c;同时保留mvn package生成的jar/war为.origin&#xff1b;重新打包存在的jar或者war包从而使他们可以在命令行使用…

eMMC安全简介

1. 引言 术语“信息安全”涵盖多种不同的设计特性。一般而言&#xff0c; 信息安全是指通过实践防止信息遭受未经授权的访问、使用、披露、中断、篡改、检查、记录或销毁。 信息安全的三大核心目标为 机密性&#xff08;Confidentiality&#xff09;、完整性&#xff08;Integr…

Python 数据结构 2.时间复杂度和空间复杂度

Life is a journey —— 25.2.28 一、引例&#xff1a;穷举法 1.单层循环 所谓穷举法&#xff0c;就是我们通常所说的枚举&#xff0c;就是把所有情况都遍历了的意思。 例&#xff1a;给定n&#xff08;n ≤ 1000&#xff09;个元素ai&#xff0c;求其中奇数有多少个 判断一…

FFmpeg-chapter3-读取视频流(原理篇)

ffmpeg网站&#xff1a;About FFmpeg 1 库介绍 &#xff08;1&#xff09;libavutil是一个包含简化编程函数的库&#xff0c;包括随机数生成器、数据结构、数学例程、核心多媒体实用程序等等。 &#xff08;2&#xff09;libavcodec是一个包含音频/视频编解码器的解码器和编…

面试(进阶) —虚拟列表在什么场景使用,如何实现?

面试(进阶) —虚拟列表在什么场景使用&#xff0c;如何实现&#xff1f; 在前端开发中&#xff0c;当需要渲染大量数据时&#xff0c;传统的渲染方式往往会遇到性能瓶颈。一次性将大量数据渲染到DOM中&#xff0c;不仅会导致页面加载缓慢&#xff0c;还可能占用大量内存&#x…

Linux Mem -- 关于AArch64 MTE功能的疑问

目录 1.虚拟地址和物理地址映射完成后&#xff0c;才可以设置虚拟地址对应的memory tag &#xff1f; 2.各种memory allocator中的address tag从哪来&#xff0c;怎么产生&#xff1f; 2.1 vmalloc allocator 2.2 slub分配器 2.3 用户可以指定IRG指令产生的address tag 3.kasan…

python-leetcode-颜色分类

75. 颜色分类 - 力扣&#xff08;LeetCode&#xff09; class Solution:def sortColors(self, nums: List[int]) -> None:"""Do not return anything, modify nums in-place instead."""low, mid, high 0, 0, len(nums) - 1while mid < h…

ArcGIS Pro技巧实战:高效矢量化天地图地表覆盖图

在地理信息系统&#xff08;GIS&#xff09;领域&#xff0c;地表覆盖图的矢量化是一项至关重要的任务。天地图作为中国国家级的地理信息服务平台&#xff0c;提供了丰富且详尽的地表覆盖数据。然而&#xff0c;这些数据通常以栅格格式存在&#xff0c;不利于进行空间分析和数据…

【江科大STM32】TIM输出比较(学习笔记)

本章图片文字内容也为重要知识&#xff0c;请马住&#xff01; 输出比较简介 OC&#xff08;Output Compare&#xff09;输出比较输出比较可以通过比较CNT与CCR寄存器值的关系&#xff0c;来对输出电平进行置1、置0或翻转的操作&#xff0c;用于输出一定频率和占空比的PWM波形…

【网络安全 | 漏洞挖掘】利用文件上传功能的 IDOR 和 XSS 劫持会话

未经许可,不得转载。 本文涉及漏洞均已修复。 文章目录 前言正文前言 想象这样一个场景:一个专门处理敏感文档的平台,如保险理赔或身份验证系统,却因一个设计疏漏而成为攻击者的“金矿”。在对某个保险门户的文件上传功能进行测试时,我意外发现了一个可导致大规模账户接管…