利用Formik解决表单痛点 #93
zhangyu1818
announced in
zh-cn
Replies: 0 comments
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
-
一直觉得表单问题是非常复杂,如何能够优雅的获取表单的值,又如何能优雅的展示不同的报错信息?
幸好现在是框架时代,如果用
jQuery
来做,想想也复杂以前写
PC
端页面,多是管理系统,表单的处理非常的简单了,因为有ant design
,我觉得ant-design
在后台管理的ui框架中,是王者级别的,它的处理非常的简单,表单错误信息也展现的如此的完美但是最近一直在做微信端的页面,自然用不了
ant-design
,表单验证就比较复杂,刚开始不知道天高地厚,自己造了个useForm
的轮子,博客也有记录,就是一个非常简单的轮子,后来功能越来越多,也就越改越乱,索性放弃了后来才发现,其实针对表单问题,在
github
有非常多的解决方案,其中在我发现的方案中,star
最多的是formik
Formik
formik
的描述是它主要解决3个问题
form
状态树的内部或外部获取数据使用
formik
后,整个表单的状态就由它接管了,values
、submit
、errors
,表单组件onChange
都被接管,也控制整个表单的更新formik
主要有2种使用方式,一种是render props
,另一种则是趋势之hooks
,它的状态保存使用的是React
的Context
render props示例
一个简单的示例
Formik
组件接收2个必需的props
initialValues
表单的初始值onSubmit
表单的提交事件对于表单控件值和控制的判断是根据表单控件的
name
属性render props
其实就是把props.children
当作函数调用,传入的props
非常多,举几个常用的handleSubmit: (e: React.FormEvent) => void
提交表单,formik
会判断仅当表单数据通过验证的时候才会调用函数handleReset: () => void
重置表单handleChange: (e: React.ChangeEvent) => void
表单控件onChange
函数handleBlur: (e: any) => void
表单控件onBlur
失焦函数,如果需要使用touched
,这个函数是必要的values: { [field: string]: any }
表单的值touched: { [field: string]: boolean }
表单控件是否被点击过errors: { [field: string]: string }
表单的错误信息isSubmitting: boolean
表单提交事件是否正在pending
,formik
会等待传入的onSubmit
事件执行完毕,这个值会从函数开始调用 ->true
-> 调用结束 ->false
,很方便的用在loading
状态的展示formik控制自定义组件
最简单的方式,就是将需要的值
value
和改变值的handleChange
作为props
传入组件,不过这种方式就很笨,formik
也同样提供了render props
和hooks
两种方式Field
render props
的方式,不多介绍useField()
hooks
的方式,一个简单的例子useField
接受一个参数,即是表单控件的name
属性,formik
是根据name
来判断哪一个组件对应哪一个值的,这个name
值必须和传入<Formik/>
的initialValues
的一个字段相同它返回一个2个元素的数组,分别是
FieldProps
和FieldMetaProps
,以下分别列举几个常用的FieldProps
value: any
当前name
对应的表单值onChange: (e: React.ChangeEvent<any>) => void
控制值改变的onChange
事件onBlur: () => void;
失焦onBlur
事件FieldMetaProps
touched: boolean
是否点击过组件error?: string
有错误信息是string
,没有是undefined
表单的验证
表单的验证也是一个比较麻烦的事情,因为一个字段可能有多种错误信息,如
至少4位
、最多6位
、不能为空
formik
也提供了验证props
—validate
,接收一个函数,这个函数接受1个必要参数values
,返回一个errors
对象,如果errors
对象里的键名和表单字段对应,则会将error
传给对应的表单控件如上所示,如果使用
if-else
来完成多种错误信息的判断,那代码也太冗长了,一旦有变化,修改起来也很麻烦,好在formik
内置了一个非常不错的验证方案yup
,这里不再多做介绍,直接看例子与自己写验证函数不同的是,使用
yup
对应的prop
是validationSchema
使用这些强大的库,一切都变得美妙了起来
写一个简单的例子
介绍了如何使用
<Formik/>
来控制表单状态和使用useField
来进行组件分离,下面写一个简单的例子自定义
input
组件使用
yup
来验证使用
Formik
onSubmit
函数如果返回一个Promise
或者是async/await
函数,formik
会自动处理isSubmitting
,如果使用异步函数的话,还需要接收第二个参数,里面有一个setSubmitting
来手动修改提交状态总结
这里介绍的方法只是
Formik
的一小部分,运用这一小部分已经能完成很多功能了yup
是个非常简洁的库,但是研究下来,好像没有能直接把错误信息作为errors
对象输出的方法,就连Fomrik
也是for
循环一个一个取的除了
Formik
,还有不少方案,如react-final-form
,这个我也使用过,感觉上实现方法大致可能是相同的,不过它像redux
一样,分为了final-form
和react-final-form
,也就是一个通用的方案,感觉还是很不错,它不像Formik
一样,必须设置初始值,感觉设置初始值大多数时候都是多余的另外有一个轻量化的
react-final-form-hooks
,它没有使用Context API
ant design
的方案我还没有研究过,它使用的验证方案是**async-validator**,我也没研究过😂,有空还需要多研究,记得一年前的我想看ant design
的源码,发现基本看不懂,最近看了Button
和Input
的源码,发现基本能看懂了,仔细回顾这一年的成长还是挺多的我觉得表单的性能优化也是一部分,不过基本没有考虑过这些,哎,每次使用这些方便好使的库,就感觉开发者很牛皮,我也想成长啊!
Beta Was this translation helpful? Give feedback.
All reactions