1、本文对Formik文档进行了归纳整理, https://formik.org/docs ,并结合源码,总结了学习心得,供大家参考
2、本文Formik版本:v2.x
一、简介:
1、什么是Formik:是由React组件和hooks组成,它内置了表单的state管理操作,无需我们在单独为表单建立state,同时使用了Context,能够让表单组件多层嵌套,不再需要我们一层层传递。
2、解决哪些问题:
- 使值进入和脱离表单状态
- 验证和错误消息
- 处理表格提交
二、起步
1、安装
$ yarn add formik
或
$ npm install formik --save
或
<script src="https://unpkg.com/formik/dist/formik.umd.production.min.js"></script>
2、推荐的校验库 Yup
学习文档推荐:https://www.zhihu.com/search?type=content&q=Yup%20js
官方文档:https://github.com/jquense/yup
$ yarn add yup
或
$ npm install yup --save
3、可以结合第三方UI库一起使用
4、Formik提交流程
提交前:
- 触摸所有字段。
initialValues
是必需的,应该始终指定。 - 设置
isSubmitting
于true
- 增量
submitCount
+1
校验:
- 设置
isValidating
于true
- 运行所有字段级别的验证
validate
,并validationSchema
异步深入地合并结果 - 有没有错误?
是:中止提交。设置isValidating
为false
,设置为errors
,设置isSubmitting
为false
否:设置isValidating
为false
,继续“提交”
提交:
- 运行您的提交处理程序
- 调用
setSubmitting(false)
5、校验
https://formik.org/docs/guides/validation, 这里写的很详细,标明了何时会触发校验
三、组件用法
1、<Field />
as:
input
select
textarea
有效的HTML元素名
React组件
children: 是个react组件, 接收这3个参数
-
field
: 当前这个Field的onChange
,onBlur
,name
, andvalue
的一些属性和方法 -
form
: 跟整个form有关的属性和方法,整个Formik包 -
meta
:value
,touched
,error
, andinitialValue
等
component:接收一个组件,( { field, form, ...props }) => ()
innerRef:回调函数,接收一个DOM节点
name: 字段名称,name也可以接受类似lodash的点路径,例如:
social.facebook 相当于:social = {facebook}
friends[0].firstName 相当于:friends = [firstName]
权重:children > component > as
2、<FieldArray />
渲染子节点方法:
- <FieldArray name="..." component>
- <FieldArray name="..." render>
- <FieldArray name="..." children>
<FieldArray
name="friends"
render={({ move, swap, push, insert, unshift, pop }) => (
<Form>
{/*... use these however you want */}
</Form>
)}
/>
push: (obj: any) => void: 向数组中添加一条
swap: (indexA: number, indexB: number) => void: 交换数组中的两个值
move: (from: number, to: number) => void: 移除某条至某处
insert: (index: number, value: any) => void: 在给定索引处插入一个元素到数组中
unshift: (value: any) => number: 在数组的开头添加一个元素并返回它的长度
remove<T>(index: number): T | undefined: 删除数组中的某条
pop<T>(): T | undefined: 从数组的末尾移除并返回值
replace: (index: number, value: any) => void: 将给定索引处的值替换到数组中
3、<ErrorMessage />
children?: ((message: string) => React.ReactNode)
component?: string | React.ComponentType<FieldProps>
name: string
render?: (error: string) => React.ReactNode
注意: 接受到的错误信息必须是string类型,其他类型会报错
4、<Form />
Form组件都干了啥?
1、在<form>标签基础上进行封装
2、接收Formik传下来的参数,把form标签自带的方法传进去
5、<FastField />
<FastField />
是<Field />
用于大型表单(〜30多个字段)或字段具有非常昂贵的验证要求的优化版本。<FastField />
具有与完全相同的API <Field>
,但在shouldComponentUpdate()
内部实现以阻止所有其他重新渲染,除非<FastField />
对Formik
状态的的相关部分/片段进行了直接更新。如果您的表单中的<Field />与其他所有<Field />
表单“无关” ,则可以使用<FastField />
,它不依赖于顶级其他部分<Formik />
的状态。
6、<Formik />
- <Formik component>
- <Formik children>
每个渲染方法将传递相同的参数,Formik
组件本身没干啥,是个壳子,用于渲染,传递useFormik的参数。排了一下渲染方法的权重:component
>render
>children
>null
。
具体每个参数是干嘛的,详见:https://formik.org/docs/api/formik,英文看不懂的话,谷歌翻译一下吧~我会归类说明,细节还得看原文档。
四、hooks
1、useField
const [field, meta, helpers] = useField(propsOrFieldName);
2、useFormikContext
const formik = useFormikContext();
3、useFormik
const formik = useFormik();
五、方法:
1、connect
将传进来的组件,传个formik对象,共享formik里的属性和方法
六、Yup的优点缺点
优点:功能强大
缺点:
1、复用性不强,因为他是链式结构
2、一坨,没有json-schema看起来简单直接