相关依赖及版本
1 2 3 4 5 6 7
| { "@material-ui.core": "4.11.3", "react-hook-form": "7.1.1", "react": "17.0.2", "react-dom": "17.0.2", "react-scripts": "4.0.0" }
|
本系列所有文章示例中的依赖均以上述为标准,或者查看对应示例代码CodeSandbox中的版本。
React Hook Form 是一个高性能、灵活。抑郁校验的表单库。可以用更少的代码获得更好的性能。
详细信息请查看React Hook Form官方文档。
需求分析
实现一个带有输入名称、网址来添加书签的表单
编写代码
基础代码
引入需要的模块
1 2 3
| import React from "react"; import {Controller, useForm} from "react-hook-forn"; import {Botton, TextEield} from "@material-ui/core";
|
定义接口
1 2 3 4
| interface FormType { name: string; url: string; }
|
编写form组件
1 2 3 4 5 6 7 8 9 10 11
| export default function App() { return ( <div className="App"> <form> <TextField label="名称" size="small" variant="outlined" /> <TextField label="网址" size="small" variant="outlined" /> <Button color="primary">提交</Button> </form> </div> ) }
|
这是一个最基础的表单,不包含事件。
Materal UI 对于表单部分的描述简单,仅有按钮、输入框等组件。从这点上对比Ant Design React的form组件显得过于简单。但同时简单意味着可以根据需求做二次封装,相比Antd的拿来就可以用,Material UI则需要一些额外的东西才可以实现效果。
因此使用React Hook Form显然是一个方便的选择。但它的文档中案例均以原生为基础,没有涉及到UI库的案例,这就导致使用UI库结合React Hook Form上手时往往会出现很多意外的问题。
使用 useForm
和 Controller
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
| export default function App() { const {control, handleSubmit} = useForm<FormType>(); const [value, setValue] = React.useState({} as FormType);
const onSubmit = (val: FormType) => { setValue(val); }
return ( <div className="App"> <form onSubmit={handleSubmit(onSubmit)}> {/* ... */} </form> </div> ) }
|
useForm()
参数请查看:useForm Api,这里我们需要 control
和 handleSubmit
这两个部分。
control
用于将组件注册到React Hook Form
handlSubmit
则是表单校验通过时返回数据的事件
使用 Controller
组件控制输入框
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| export default function App() { const { control, handleSubmit } = useForm<formType>(); const [value, setValue] = React.useState({} as formType);
const onSubmit = (val: formType) => { setValue(val); };
return ( <div className="App"> <form onSubmit={handleSubmit(onSubmit)}> <Controller control={control} name="name" render={({ field: { onChange, ref }) => { return ( <div style={{ display: "block", margin: "10px 0" }}> <TextField label="名称" size="small" variant="outlined" onChange={onChange} inputRef={ref} /> </div> ); }} /> <Controller control={control} name="url" render={({field: { onChange, ref }}) => { return ( <div style={{ display: "block", margin: "10px 0" }}> <TextField label="网址" size="small" variant="outlined" onChange={onChange} inputRef={ref} /> </div> ); }} /> <Button type="submit" color="primary" variant="contained"> 提交 </Button> </form> 数据:{JSON.stringify(value)} </div> ); }
|
主要使用的属性:control、name、render具体请看Controller Api
添加校验
现在表单就可以正常使用了,接下来还需要添加校验
Controller
中有一个名为 rules
的属性具体参数参考 useForm()
的 register
属性。
1 2 3 4
| <Controller {...} rules={{resuired: true}} />
|
现在最基本的使用方式就是这样了,最后是完整的例子:
本文案例(CodeSandbox)