Formik --- 一个 React 表单库

Formik 受控表单库

最近使用antd Form 有点痛苦,看到 React 官网推荐了 Formik 表单库,所赶紧去搂了一遍官网,下面是一个大概的介绍,具体使用之后再慢慢更新😝

  1. handleChange/setFieldValue —— 通过 setFieldValue 或 handleChange 模拟事件,可以同时修改多个 input 的值

  2. values —— 通过拦截、篡改 values ,直接影响表单显示的值

  3. errors —— 通过拦截、篡改 errors ,方便自定义表单验证消息

这个表单库在运作中始终保持 single source of truth(单一数据源) —— view 的数据始终来自 values 和 errors,表单值的变化始终由 handleChange 发起

其实 useFormik() 还返回了 setFieldError 函数,可以用来设置 errors。 这个设计类似于 setFieldValue。

但是 setFieldError 和 setFieldValue 都会触发重新渲染,所以使用不当会造成无限循环渲染。

Formik 每一次修改都会触发整个表单的全局渲染。 但是其实 formik 最推崇的 FastField + ErrorMessage 的形式是可以有效避免这个问题的,这两个组件都在 shouldComponentUpdate 做了简单的浅层比较来避免不必要的重新渲染。

formik 和 antd 组合使用的例子

在输出错误信息的时候,通常有 touched.name && errors.name && errors.name 的判断,这个判断不依赖与 onBlur 事件的绑定这是因为 formik 在做表单校验的时候,会将全字段都检查一遍,不管用户有没有操作,但是对于用户来说,通常不希望在还没有操作的字段显示一行错误信息,所以需要 touched 字段查看该字段是否已经操作过,操作过并且有错误,才显示。
通过 Formik 组件传入初始字段,校验规则,提交事件;并在表单中绑定上 handleSubmit,handleChange,handleBlur 等事件后,我们就能够实现一个简单表单操作。

如果您熟悉使用普通 React 构建表单,您可以认为 Formik 的 handleChange 工作方式如下:

 const [values, setValues] = React.useState({});

 const handleChange = event => {
   setValues(prevValues => ({
     ...prevValues,
     // we use the name to tell Formik which key of `values` to update
     [event.target.name]: event.target.value
   });
 }

formik.errors 通过自定义验证函数填充。默认情况下,Formik 将在每次击键(更改事件)、每个输入的模糊事件以及提交之前进行验证。onSubmit 我们传递给的函数 useFormik()只有在没有错误时才会执行(即如果我们的 validate 函数返回{})

getFieldProps()

上面的代码非常明确地说明了 Formik 正在做什么。onChange-> handleChange、onBlur->handleBlur 等。但是,为了节省您的时间,useFormik()返回一个调用的辅助方法 formik.getFieldProps(),以加快连接输入的速度。给定一些字段级别的信息,它会为您返回给定字段的 onChange, onBlur, value。然后,您可以传播上的 input,select 或 textarea。

代码由

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

转换为

<input id="email" type="email" {...formik.getFieldProps('email')} />

使用 useField 来包装我们自己的组件

const MyTextInput = ({ label, ...props }) => {
   // useField() returns [formik.getFieldProps(), formik.getFieldMeta()]
   // which we can spread on <input>. We can use field meta to show an error
   // message if the field is invalid and it has been touched (i.e. visited)
   const [field, meta] = useField(props);
   return (
     <>
       <label htmlFor={props.id || props.name}>{label}</label>
       <input className="text-input" {...field} {...props} />
       {meta.touched && meta.error ? (
         <div className="error">{meta.error}</div>
       ) : null}
     </>
   );
 }

默认情况下,Formik 将按如下方式运行验证方法:

  1. 在“更改”事件/方法(更新的东西 values)之后
  • handleChange

  • setFieldValue

  • setValues

  1. 在“模糊”事件/方法(更新的东西 touched)之后
  • handleBlur

  • setTouched

  • setFieldTouched

  1. 每当尝试提交时
  • handleSubmit

  • submitForm

  1. 还有通过 Formik 的渲染/注入道具提供给您的命令式辅助方法,您可以使用它们来命令式调用验证。
  • validateForm

  • validateField

我可以将 null 作为错误消息返回吗?
不,请 undefined 改用。Formik 用于 undefined 表示空状态。如果您使用 null,Formik 的计算道具的几个部分(isValid 例如)将无法按预期工作。

使用 isSubmittimg 来防止表单重复提交

formik 动态添加或删除某一项

感觉和 antd 还是有点像

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 213,928评论 6 493
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 91,192评论 3 387
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 159,468评论 0 349
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 57,186评论 1 286
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 66,295评论 6 386
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 50,374评论 1 292
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 39,403评论 3 412
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,186评论 0 269
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 44,610评论 1 306
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 36,906评论 2 328
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,075评论 1 341
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 34,755评论 4 337
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,393评论 3 320
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,079评论 0 21
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,313评论 1 267
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 46,934评论 2 365
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 43,963评论 2 351

推荐阅读更多精彩内容