React-Hook-Form 的常见用例
React-Hook-Form 库 |常见用例
因为绝对没有人喜欢通过验证来创建和重建复杂的表单
失败是成功之母 — — failure is the mother of success
表单状态管理一直是让我头疼的问题,错误处理、验证规则、表单重置。 . .幸运的是,近年来出现了很多很好的解决方案,例如 甲酸 , 反应挂钩形式 , 反应最终形式 , 重新启动 , ETC。
由于最近有人问我是否知道 React-Hook-Form 并且由于我从未使用过它,所以我决定从这个钩子开始并创建一个简单的表单以便我更好地理解它,当然我会分享步骤在这篇文章中和你一样喜欢我的其他文章
让我首先展示最终结果应该是什么样子,这样我们就有了一个清晰的想法。对于表单,我将提供用户名、密码作为输入字段和城
end result form with validation
首先,让我们创建所有没有功能的输入字段和按钮。应用结构相当简单,父组件 应用程序 包含子组件 国家 (黄色轮廓)。
// **应用程序**
从“./Country”导入国家;
进口 ... 导出默认函数 **应用程序** () {
返回 (
<div className="App">
<form onSubmit={...} >
<fieldset>
<legend>用户资料</legend>
<div className="...">
<label>名:</label>
<input .../>
</div>
<div className="...">
<label>姓:</label>
<input ... />
</div>
<div className="...">
<label>密码:</label>
<input ... />
</div>
<div className="...">
< **国家** />
</div> <input type="submit" value="提交" />
<button onClick={...}>部分重置</button>
</fieldset>
</form>
</div>
)}
// **国家**
常量国家 = () => {
返回 (
<>
<label>城市:</label>
<div>
<select>
<option value="">选择</option>
<option value="Hongkong">香港</option>
<option value="Shenzhen">深圳</option>
<option value="Shanghai">上海</option>
</select> <button type="button" onClick={...}>获取值</button>
</div>
</>
)}; 出口默认国家;
使用 React 开发时,我们通常会创建一个 受控形式 ,这意味着我们直接使用 React 处理数据,而不是让 React 隐式处理数据。
例如,我们可以使用一些 React 内置 像钩子 使用状态 存储每个字段的值。当用户键入时,我们需要通过捕获一些事件处理程序来获取更新并将它们应用于字段值,这就是受控表单的用武之地。
常量 [ **密码** , setPassword] = useState("");
常量句柄密码更改 = (e) => **设置密码** (e.target.value); <input type="password" name="password" value={ **密码** } onChange={handlePasswordChange} />
简单的表格就可以了。但是,如果我们遇到复杂的表单,比如多步骤的表单、联动效果、多层结构等,这就意味着我们需要更多的useState、useEffect……钩子,更多的onChange、onClick……handlers,更多的字段需要添加到表单中,需要创建更多的处理程序和状态。这会增加我们代码的长度并增加其不可读性。
为了防止这样的事情发生,我们可以使用 React Hook 表单库,这将帮助我们创建轻量级、强大、灵活、可采用和可扩展的表单,并具有用户友好的验证,并且直观、功能完整的 API 在构建时提供无缝体验形式。
React Hook Form 是一个没有任何依赖关系的小型库,它最大限度地减少了验证计算,减少了您需要编写的代码量,同时消除了不必要的重新渲染,并且可以在没有其他依赖项的情况下轻松采用。
要使用 react-hook-form,我们需要 进口 和 称呼 这 ** 使用表格** 钩。当我们这样做时,目的是设置将在链接到表单的所有字段之间共享的表单管理和状态。 useForm 返回一个 目的 其中包含有用的功能( ** 登记** , 设定值 , 获取值 , 处理提交... )。
我们将解构并尝试 登记 第一的。
*登记 是一个回调函数,它返回一些 ** 道具** 并注入输入,以便我们可以控制和读取输入,它允许我们将输入连接到由定义的表单 ** 使用表单(),** 它返回 4 个重要属性:
改变
订阅输入更改事件的道具。
模糊
订阅输入模糊事件的道具。
参考
要注册的挂钩表单的输入参考。
姓名
输入的名称正在注册。
现在让我们更新我们的输入字段并添加一个提交处理程序,调用注册函数并提供输入的名称:
进口 { **使用表格** } 来自“反应钩子形式”; 导出默认函数 App() {
常量 { **注册,处理提交** } = useForm();
返回 (
...
<form onSubmit={ **处理提交** ((值)=> console.log(“值”,值))}
<input {... **登记** ("名字")} />
<input {...register("lastName")}/>
<input {...register("password")}/>
<input {...register("city")}/> <input type="submit" value="提交" />
</form>
...
)}
现在,当我们提交表单时,我们将在控制台中看到所有值,如下所示,将它集成到我们的表单中真的很容易。
register Input values
在下一步中,我们可以执行 验证 对于输入字段,验证可以定义为 通过一个 目的 与 需要规则 到寄存器功能作为 范围 .
// 名字验证
<input {...register(" **名** ",
{
**必需的** : "名字是必填项"
})} /> // 姓氏验证
<input {...register(" **姓** ",
{
**必需的** : 真的,
**最小长度** : {
**价值** : 3,
**信息** : "姓氏是必填项,至少应包含 3 个字符" }
})} />
现在刷新页面,将 firstName 字段留空并在 lastName 字段中仅键入一个字符并提交表单。在此过程中,将首先执行验证,这涉及检查 验证规则 在寄存器函数中定义。 (在我们的例子中:需要 信息 , 最小长度 …)
注意有 不 重新渲染 完全没有,但我们专注于正确的输入( 名 input field ) 提交后,实际上会导致验证错误。
这是因为 react-hook-form 的渲染处理得很好,如果我们不订阅错误状态,它不会触发重新渲染!
为了查看错误消息,我们可以简单地订阅错误,使用 表单状态 并在适当的输入下渲染它们。
常量 { 注册 **,** 处理提交, **表单状态:{错误}** } = useForm(); <input {...register(" **姓** ", {...})} />
<p>{ **错误** . **姓** ?. **信息** }</p>
reading and rendering errors with formState
然而,它 推荐 提供 默认值 在 useForm 中,输入的 defaultValues 用作首次呈现组件时的初始值,然后再与用户交互。
常量默认值 = {
名字:“萝拉”,
lastName: “Zhu”,
密码: ””,
**城市:“香港”**
}; 常量 {...} = **使用表格** ({ **默认值** });
现在刷新页面,我们应该看到:
default values provided
我们还可以设置 模式 表单中,mode可以控制触发验证的时机。如果我们希望用户尽快感知到错误,我们可以使用“ 全部 ”:
常量 {...} = useForm({
默认值 **,**
**模式** : “全部” _// onChange |模糊 |提交 |触摸 |全部
_ });
到目前为止一切看起来都很好,但是如果我们想多次订阅某个输入值怎么办?例如我们想使用指定的输入并用它做一些事情......我们可以使用 手表 API。
此方法将监视指定的输入并返回它们的值。渲染输入值和根据条件确定要渲染的内容很有用。
常量 { ..., **手表** } = useForm({ ... });
默认情况下,当您在输入字段中键入内容时,react-hook-form 不会触发任何重新渲染,而是通过调用 手表 函数,我们可以订阅输入,当我们 控制台日志 看,我们看到了所有的价值观。
控制台.log(“手表”,手表());
console.log(“watch”, watch())
我们还可以“ 手表 ” 指定输入并返回它们的值:
常量密码值= {密码:手表(“密码”)}; const watchFields = watch([“密码”, “城市”]); console.log(“watch”, password_value, watchFields);
console.log watch values
注意事项:
-
Watch 将在应用程序或表单的根目录触发重新渲染,考虑使用回调或 使用手表 如果您遇到性能问题,请使用 API。
-
还有一个 ** 获取值** 用于读取输入值的辅助 API,两者的区别
_手表_
和_获取值_
就是它_获取值_
__将不会 触发重新渲染或订阅输入更改。_// {firstName:"Lola",lastName:"Zhu",password:"...",city:"Hongkong"}
_ 常量值 = 获取值() ; _// “香港”
_ 常量单值 = 获取值(“城市”) ; _// ["Lola","Zhu","Hongkong"]
_ 常量多值 = getValues(["firstName", "lastName", "city"]) ;
记得上面我们有 国家 组件作为子组件?要从子组件访问表单方法和状态,我们可以像往常一样传递 props,但是因为有一个 使用上下文 在 React 中的钩子,我们在 react-hook-form 库中也有一个钩子: 使用表单上下文 ,它的行为与 React 的 useContext 非常相似。
useFormContext 旨在用于 深度嵌套的结构 在传递 props 变得不方便的地方,它允许我们访问表单上下文,获取表单提供的方法和状态 使用表格 无需再次调用钩子。
要使用 useFormContext,我们使用 ** 表单提供者** __ 将表单数据发送给子孙子级的包装器,并通过以下方式访问它们 ** 使用表单上下文** 钩。
-
在 App 组件中导入 FormProvider
进口{使用表格, 表单提供者 } 来自“反应钩子形式”; 导出默认函数 App() {
常量 { 注册 , getValues, ...} = useForm();
返回 (
...
< 表单提供者 {...{注册,获取值}}> -
检索所有钩子方法 使用表单上下文 内部子组件 国家
进口 { 使用表单上下文 } 来自“反应钩子形式”; 常量国家 = () => {
// 获取钩子方法
常量 { 登记 , 获取值 } = useFormContext();
返回 (
<>
常量值 = **获取值** (); _ _ const singleValue = getValues("city"); _ _ 常量multipleValues = getValues( [“密码”,“姓氏”,“城市”]); // console.log(values, singleValue, multipleValues); }}>获取值)}; 出口默认国家;
好的!最后一个有用的 API 是 重置 ,它会重置所有表单状态、字段引用和订阅。
重置听起来很简单,但实际上用户想要重置表单有很多不同的情况。例如,有时我们想将表单重置为初始状态或重置/更新状态,或者将表单重置为一些部分值......。等等
在我们的示例中,我们在 App 组件中有一个重置按钮,我将尝试实现其中一些情况:
<button onClick={...}>部分重置</button>
-
第一种情况:将表单重置为 最初的 状态。 * reset 提供的第一个参数实际上是可选的 ,这意味着如果我们在没有任何参数( reset() )的情况下执行该函数,react-hook-form 会将表单重置为您提供的默认值。如果未提供 defaultValues,则 HTML 原生 重置 将调用 API 来恢复表单。
const { ...,reset } = useForm(); 常量 resetForm = () => 重置 ();
-
第二种情况:重置和更新表单值。 * 如果我们想将整个表单重置为不同的值,还要更新默认值,那么我们可以提供 ** 价值。** 提供值后,单击重置按钮后, 不仅 UI 中的值将被更新,但我们存储在 react-hook-form 中的 defaultValue 也会被反映,在我们下面的代码中,重置后,城市将是“上海”而不是默认的“香港”。
常量 resetForm = () => {
重置((formValues)=>({
…表单值,
城市:“上海”
}));
}
-
第三种情况:抓住一切并 部分 重置表格。 * 我们可以将上面解释的 getValues API 与 Reset API 结合起来 .这意味着我们可以做到 浅合并 与表单中实际当前的内容并合并我们要应用的值。
在这种情况下,其他输入值保持不变,但 ** 名** 被重置为“迷你”。
常量 resetForm = () => {
重置({
...获取值,
**名** :“ **小型的** ",
});
}
<button onClick={resetForm}>部分重置</button>
好的!到目前为止,我想我已经介绍了一些常用的 API,还有更多我在不断学习的自定义钩子(例如 使用控制器 , 使用手表 , 使用表单状态 , 使用字段数组 ),以及更多方法(例如 设置焦点 , 获取字段状态 , 重置字段 , 设定值 … ETC )。但希望这个例子能激发你尝试这个库
就是这样!你可以找到完整的代码 这里 ,玩吧 😃 感谢您的宝贵时间! ⏰
如果你也对我的其他文章感兴趣,这里有一些链接:
[
使用 React Hook useReducer 创建购物清单
一个带有 useReducer React Hook 的购物清单——一个让 useReducer 更容易理解的小练习。
javascript.plainenglish.io
](https://javascript.plainenglish.io/a-shopping-list-with-react-hook-usereducer-310a3b6578)
[
创建一个简单的 React 自定义 Hook
一个关于如何创建一个简单的 React 自定义钩子的教程
javascript.plainenglish.io
](https://javascript.plainenglish.io/create-a-simple-react-custom-hook-fc733d7b977a)
[
为 React 应用程序创建一个简单的 Express 服务器 (Node.js)
关于如何创建简单的 Express 服务器 (Node.js)、将其连接到 React 应用程序以及解决错误的教程……
javascript.plainenglish.io
[
使用 Refs 反应功能组件
— 带有 forwardRef 和 useImperativeHandle 的示例
小民珠传媒
](https://xiaominzhu.medium.com/react-functional-components-using-refs-a5ad1d2817d4)
[
使用 React Context 将状态从子更新到父
— React Context 提供了一种通过组件树传递数据的方法,而无需在…
媒体网
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明