Formik + Yup 基本使用、表单验证、自定义控件

阅读: 评论:0

Formik + Yup 基本使用、表单验证、自定义控件

Formik + Yup 基本使用、表单验证、自定义控件

Formik 介绍和基本使用

介绍

Formik 是 React 官方推荐使用的用于增强表单处理能力,简化表单处理流程的第三方模块。

让开发者更建单的开发表单,更专注于业务。

包含验证、追踪访问字段以及处理表单提交的完整解决方案。

基本使用

使用 formik 进行表单数据绑定及表单提交处理。

只需要使用 formik 创建一些内容,然后将这些内容与 form 表单进行绑定即可:

  • formik 提供一个 useFormik 方法用于创建表单内容,它接收一个配置对象,可以配置:
    • initialValues:表单的默认数据
    • onSubmit:表单提交事件处理函数,它接收表单数据作为参数
      • 不需要手动书写阻止表单默认行为的代码,默认 formik 进行了阻止
  • formik 创建的内容用于表单绑定,包含
    • values:表单数据
    • handleSubmit:表单提交事件处理函数
    • handleChange:表单项的 onChange 事件处理函数,用于数据同步
  • 每个表单项通过 name、value、onChange 与 formik 创建的内容进行绑定
# 安装
npm install formik
import { useFormik } from 'formik'
function App() {const formik = useFormik({initialValues: {username: '张三',password: '123456'},onSubmit: values => {console.log(values)}})return (<form onSubmit={formik.handleSubmit}><div><inputtype="text"name="username"value={formik.values.username}onChange={formik.handleChange}/></div><div><inputtype="password"name="password"value={formik.values.password}onChange={formik.handleChange}/></div><input type="submit" /></form>)
}export default App

Formik 表单验证

初始验证

useFormik 可以配置表单验证方式 validate

validate 是一个函数,接收表单数据作为参数。

validate 要求返回一个对象,对象的 key 是验证不通过的表单项的 namevalue 是验证失败的提示信息。

useFormik 返回的对象包含 errors,就是验证方法返回的结果。

import { useFormik } from 'formik'
function App() {const formik = useFormik({initialValues: {username: '张三',password: '123456'},validate: values => {const errors = {}const {username, password} = valuesif (!username){errors.username = '请输入用户名'} else if (username.length > 15) {errors.username = '用户名长度不得超过15个字'}if (!password) {errors.password = '请输入密码'} else if (password.length < 6) {errors.password = '密码长度不得小于6'}return errors},onSubmit: values => {console.log(values)}})return (<form onSubmit={formik.handleSubmit}><div><inputtype="text"name="username"value={formik.values.username}onChange={formik.handleChange}/></div>{s.username && <p>{s.username}</p>}<div><inputtype="password"name="password"value={formik.values.password}onChange={formik.handleChange}/></div>{s.password && <p>{s.password}</p>}<input type="submit" /></form>)
}export default App

优化体验

体验问题:将表单默认数据设置为空,在输入用户名(焦点还未离开、密码还未改动)的时候,触发了验证,由于密码验证失败,显示了错误提示。

优化:初始数据未变更的表单项不进行校验。

方法:

  1. 开启离开焦点时触发验证
    • useFormik 返回的对象包含 handleBlur 方法,将其绑定到表单项的 onBlur 属性上,在表单失去焦点的时候会触发验证。
  2. 提示信息时检查表单元素的值是否被改动过
    • useFormik 返回对象中包含 touched 属性,它是一个对象,存储哪些表单数据发生了变化。
    • 表单项的值发生变化后,不论是否还原为初始值,touched 中的标记不会再改变。
    • 默认是 {},如果 username 表单项发生了变化,则会记录为 {username: true}
    • 只有当表单项绑定了 handleBlur 事件处理函数后,touched 才会记录
import { useFormik } from 'formik'
function App() {const formik = useFormik({initialValues: {username: '',password: ''},validate: values => {const errors = {}const {username, password} = valuesif (!username){errors.username = '请输入用户名'} else if (username.length > 15) {errors.username = '用户名长度不得超过15个字'}if (!password) {errors.password = '请输入密码'} else if (password.length < 6) {errors.password = '密码长度不得小于6'}return errors},onSubmit: values => {console.log(values)}})console.uched)return (<form onSubmit={formik.handleSubmit}><div><inputtype="text"name="username"value={formik.values.username}onChange={formik.handleChange}onBlur={formik.handleBlur}/></div>{(uched.username && s.username) && <p>{s.username}</p>}<div><inputtype="password"name="password"value={formik.values.password}onChange={formik.handleChange}onBlur={formik.handleBlur}/></div>{(uched.password && s.password) && <p>{s.password}</p>}<input type="submit" /></form>)
}export default App

Yup - 更优雅的表单验证

Yup 是一个 JavaScript 方案生成器,用于值的解析转化和验证。

# 安装
npm install yup

useFormik 的配置选项中通过 validationSchema 配置验证规则。

object() 创建验证规则,传入一个对象,key 是表单项的 name,值是 yup 的验证方法,例如:

import { useFormik } from 'formik'
import * as Yup from 'yup'function App() {const formik = useFormik({initialValues: {username: '',password: ''},validationSchema: Yup.object({username: Yup.string() // 将值(不为空时)转化为字符串.max(15, '用户名长度不得超过15个字') // 验证长度.required('请输入用户名'), // 验证必传password: Yup.string().min(6, '密码长度不得小于6').required('请输入密码')}),onSubmit: values => {console.log(values)}})return (<form onSubmit={formik.handleSubmit}><div><inputtype="text"name="username"value={formik.values.username}onChange={formik.handleChange}onBlur={formik.handleBlur}/></div>{(uched.username && s.username) && <p>{s.username}</p>}<div><inputtype="password"name="password"value={formik.values.password}onChange={formik.handleChange}onBlur={formik.handleBlur}/></div>{(uched.password && s.password) && <p>{s.password}</p>}<input type="submit" /></form>)
}export default App

getFieldProps - 减少样板代码

useFormik 返回的对象提供了一个方法:getFieldProps,可以获取指定表单项的 namevalueonChangeonBlur 属性,可以将它们直接绑定到表单项元素,减少重复代码。

// 样板代码
name="username"
value={formik.values.username}
onChange={formik.handleChange}
onBlur={formik.handleBlur}
import { useFormik } from 'formik'
import * as Yup from 'yup'function App() {const formik = useFormik(...)console.FieldProps('username'))return (<form onSubmit={formik.handleSubmit}><div><inputtype="text"{...FieldProps('username')}/></div>{(uched.username && s.username) && <p>{s.username}</p>}<div><inputtype="password"{...FieldProps('password')}/></div>{(uched.password && s.password) && <p>{s.password}</p>}<input type="submit" /></form>)
}export default App

使用组件的方式构建表单

Formik 提供了一系列组件去构建表单,一些细节代码,已经在组件中封装好了。

  • Formik:表单外层组件,用来包裹 Form 组件
    • 通过属性传递配置项,例如
      • initialValues
      • onSubmit
      • validationSchema
  • Form:表单组件,在内部包裹一个个具体的表单项
  • Field:表单项组件
    • name 属性绑定目标表单项的 name
    • 默认 Field 渲染为一个文本框
  • ErrorMessage:用于显示表单验证失败的提示信息
    • name 属性绑定目标表单项的 name
import { Formik, Form, Field, ErrorMessage } from 'formik'
import * as Yup from 'yup'function App() {const initialValues = {username: '',password: ''}const validationSchema = Yup.object({username: Yup.string().max(15, '用户名长度不得超过15个字').required('请输入用户名'),password: Yup.string().min(6, '密码长度不得小于6').required('请输入密码')})const onSubmit = values => {console.log(values)}return (<Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={onSubmit}><Form><Field name="username" /><ErrorMessage name="username" /><Field name="password" /><ErrorMessage name="password" /><input type="submit" /></Form></Formik>)
}export default App

构建其它表单控件

默认情况下,Field 组件渲染的是文本框(text),可以通过 as 属性指定表单元素类型。

import { Formik, Form, Field } from 'formik'function App() {const initialValues = {content: '内容',subject: 'JS'}const onSubmit = values => {console.log(values)}return (<Formik initialValues={initialValues} onSubmit={onSubmit}><Form><Field name="content" as="textarea" /><Field name="subject" as="select"><option value="Node">Node</option><option value="JS">JS</option></Field><input type="submit" /></Form></Formik>)
}export default App

Field 组件并没有提供现成的 password、单选框、复选框这样的表单控件,需要自己创建。

构建自定义表单控件

Formik 提供 useField 方法构建自定义表单控件,也就是自定义组件。

useField 可以获取表单项信息,返回一个数组,包含两项内容:

  • field:包含表单属性相关的内容,name,valueonChangeonBlur
  • meta:包含表单验证相关的信息
import { Formik, Form, Field, ErrorMessage, useField } from 'formik'
import * as Yup from 'yup'function MyInputField({label, name, ...props}) {const [field, meta] = useField({ name })console.log('field', field);console.log('meta', meta);return <div>{/* 由于 for 在 JavaScript 中是保留字,所以 React 元素中使用了 htmlFor 来代替。 */}<label htmlFor={props.id}>{label}</label><input {...field} {...props} />{uched &&  ? <div>{}</div> : null}</div>
}function App() {const initialValues = {username: '',password: ''}const validationSchema = Yup.object({username: Yup.string().max(15, '用户名长度不得超过15个字').required('请输入用户名'),password: Yup.string().min(6, '密码长度不得小于6').required('请输入密码')})const onSubmit = values => {console.log(values)}return (<Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={onSubmit}><Form><Field name="username" /><ErrorMessage name="username" /><MyInputField id="password" name="password" label="密码" type="password" placeholder="请输入密码" /><input type="submit" /></Form></Formik>)
}export default App

fieldmeta 打印结果:

构建自定义 checkbox 控件

  • 复选框的 onChange 事件由开发者自定义,不使用 formik 生成的
  • 不能直接修改复选框的值,需要通过 useField 返回的 helper.setValue() 方法
import { Formik, Form, Field, ErrorMessage, useField } from 'formik'
import * as Yup from 'yup'function MyCheckBox({ label, name, ...props }) {const [field, meta, helper] = useField({ name })const { value } = metaconst { setValue } = helperconsole.log('meta', meta)console.log('helper', helper)const handleChange = () => {const set = new Set(value)if (set.has(props.value)) {set.delete(props.value)} else {set.add(props.value)}setValue([...set])}return (<div><label><input type="checkbox" name={name} checked={value.includes(props.value)} {...props} onChange={handleChange} /> {props.value}</label></div>)
}function App() {const initialValues = {username: '',hobbies: ['足球', '篮球']}const validationSchema = Yup.object({username: Yup.string().max(15, '用户名长度不得超过15个字').required('请输入用户名')})const onSubmit = values => {console.log(values)}return (<Formik initialValues={initialValues} validationSchema={validationSchema} onSubmit={onSubmit}><Form><Field name="username" /><ErrorMessage name="username" /><MyCheckBox value="足球" label="足球" name="hobbies" /><MyCheckBox value="篮球" label="篮球" name="hobbies" /><MyCheckBox value="橄榄球" label="橄榄球" name="hobbies" /><input type="submit" /></Form></Formik>)
}export default App

metahelper 打印结果:

本文发布于:2024-01-30 21:42:56,感谢您对本站的认可!

本文链接:https://www.4u4v.net/it/170662217823031.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:自定义   表单   控件   Formik   Yup
留言与评论(共有 0 条评论)
   
验证码:

Copyright ©2019-2022 Comsenz Inc.Powered by ©

网站地图1 网站地图2 网站地图3 网站地图4 网站地图5 网站地图6 网站地图7 网站地图8 网站地图9 网站地图10 网站地图11 网站地图12 网站地图13 网站地图14 网站地图15 网站地图16 网站地图17 网站地图18 网站地图19 网站地图20 网站地图21 网站地图22/a> 网站地图23