Formik 是 React 官方推荐使用的用于增强表单处理能力,简化表单处理流程的第三方模块。
让开发者更建单的开发表单,更专注于业务。
包含验证、追踪访问字段以及处理表单提交的完整解决方案。
使用 formik 进行表单数据绑定及表单提交处理。
只需要使用 formik 创建一些内容,然后将这些内容与 form 表单进行绑定即可:
# 安装
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
useFormik
可以配置表单验证方式 validate
。
validate
是一个函数,接收表单数据作为参数。
validate
要求返回一个对象,对象的 key
是验证不通过的表单项的 name
,value
是验证失败的提示信息。
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
体验问题:将表单默认数据设置为空,在输入用户名(焦点还未离开、密码还未改动)的时候,触发了验证,由于密码验证失败,显示了错误提示。
优化:初始数据未变更的表单项不进行校验。
方法:
useFormik
返回的对象包含 handleBlur
方法,将其绑定到表单项的 onBlur
属性上,在表单失去焦点的时候会触发验证。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 是一个 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
useFormik
返回的对象提供了一个方法:getFieldProps
,可以获取指定表单项的 name
、value
、onChange
、onBlur
属性,可以将它们直接绑定到表单项元素,减少重复代码。
// 样板代码
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 提供了一系列组件去构建表单,一些细节代码,已经在组件中封装好了。
name
属性绑定目标表单项的 name
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
,value
、onChange
、onBlur
等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
field
和 meta
打印结果:
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
meta
和 helper
打印结果:
本文发布于:2024-01-30 21:42:56,感谢您对本站的认可!
本文链接:https://www.4u4v.net/it/170662217823031.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
留言与评论(共有 0 条评论) |