iis服务器助手广告广告
返回顶部
首页 > 资讯 > 精选 >React Hook Form优雅处理表单使用的方法是什么
  • 749
分享到

React Hook Form优雅处理表单使用的方法是什么

2023-07-05 11:07:46 749人浏览 安东尼
摘要

这篇“React Hook FORM优雅处理表单使用的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看

这篇“React Hook FORM优雅处理表单使用的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇“React Hook Form优雅处理表单使用的方法是什么”文章吧。

    受控组件与非受控组件

    受控组件

    先说说受控组件,以 input 为例:

    const [value,setValue] = useState('')<input value={value} onChange={(e)=> setValue(e.target.value)} />

    在上面的代码中,我们通过通过自己维护一个 state 来获取或更新 input 输入的值,以这种方式控制取值的 表单输入元素 就叫做 受控组件

    非受控组件

    那么什么是非受控组件呢?在 React 中,非受控组件是指表单元素的值由 DOM 节点直接处理,而不是由 React 组件来管理。如下例:

    import React, { useRef } from 'react';function UncontrolledForm() {  const nameInputRef = useRef(null);  const emailInputRef = useRef(null);  const passWordInputRef = useRef(null);  function handleSubmit(event) {    console.log('Name:', nameInputRef.current.value);    console.log('Email:', emailInputRef.current.value);    console.log('Password:', passwordInputRef.current.value);    event.preventDefault();  }  return (    <form onSubmit={handleSubmit}>      <label>        Name:        <input type="text" ref={nameInputRef} />      </label>      <label>        Email:        <input type="email" ref={emailInputRef} />      </label>      <label>        Password:        <input type="password" ref={passwordInputRef} />      </label>      <button type="submit">Submit</button>    </form>  );}

    在这个例子中,我们使用 useRef Hook 创建了一个 ref 对象,并将其赋值给每个 input 元素的 ref 属性。在 handleSubmit 函数中,我们使用 ref.current.value 来获取每个 input 元素的值。这里的每个input 元素都是非受控组件,因为它们的值由 DOM 节点直接处理,而不是由 React 组件来管理。

    当然,这意味着当用户输入数据时,React 无法追踪表单元素的值。因此,当您需要访问表单元素的值时,您需要使用DOM api来获取它们。

    为什么需要非受控组件

    在 React 中,通常使用受控组件来处理表单。受控组件表单元素的值由 React 组件来管理,当表单数据发生变化时,React 会自动更新组件状态,并重新渲染组件。这种方式可以使得表单处理更加可靠和方便,也可以使得表单数据和应用状态之间保持一致。

    但在实际的开发中,表单往往是最复杂的场景,有的表单有数十个字段,如果使用受控组件去构建表单,那么我们就需要维护大量 state,且 React 又不像 Vue 可以通过双向绑定直接修改 state 的值,每一个表单字段还需要定义一下 onChange 方法。因此在维护复杂表单时,使用受控组件会有很大的额外代码量。

    为了解决受控组件带来的问题,我们可以使用非受控组件来构建表单。受控组件主要有以下三个优点

    • 可以减少组件的 代码量和复杂度,因为非受控组件不需要在组件状态中保存表单数据。

    • 可以更好地 处理大量表单数据,因为非受控组件可以让您直接操作DOM元素,而不需要将所有表单数据存储在组件状态中。

    • 可以更容易地与第三方 javascript 库和表单处理代码集成,因为非受控组件使您能够使用 DOM API 或 ref 直接访问表单元素,而不是在 React 中重新实现所有的表单处理逻辑。

    React Hook Form 是什么?

    React Hook Form 是一个基于 React 的 轻量级表单验证库。它使用了 React Hook API,让表单验证变得简单、易用、高效。React Hook Form 的主要目标是提供一个简单易用的表单验证解决方案,同时还能保持高性能和低开销。

    React Hook Form 的特点都在官网首页 react-hook-form.com 中以可交互的形式展示,包括了以下几点:

    • 通过 React Hook 的方式减少使用时的代码量,简单易上手,并且移除了不必要的重复渲染:

    React Hook Form优雅处理表单使用的方法是什么

    • 隔离重复渲染,自组件重新渲染时不会触发父组件或兄弟组件的重新渲染:

    React Hook Form优雅处理表单使用的方法是什么

    • 订阅机制,与上一点相似,能够订阅单个输入和表单状态更新,而无需重新呈现整个表单:

    React Hook Form优雅处理表单使用的方法是什么

    • 组件渲染速度足够快,而且代码库非常小,压缩后只有几 KB 大小,不会对页面性能造成任何影响:

    React Hook Form优雅处理表单使用的方法是什么

    React Hook Form 的使用姿势

    数据收集

    先看看最基础的表单实现:

    import React from "react";import { useForm } from "react-hook-form";function MyForm() {  const { reGISter, handleSubmit } = useForm();  const onSubmit = (data) => console.log(data);  return (    <form onSubmit={handleSubmit(onSubmit)}>      <input {...register("firstName")} />      <input {...register("lastName")} />      <button type="submit">Submit</button>    </form>  );}

    咱们来分析一下这段代码:

    • 使用 useForm 函数创建一个表单对象,该函数返回一个包含 registerhandleSubmit 等方法的对象。

    • 在表单中定义两个输入框,使用 register 函数注册表单输入组件,并指定组件的名称为 firstNamelastName

    • 使用 React Hook Form 提供的 handleSubmit 函数来管理表单的提交和数据验证。

    这里我们不需要定义任何 state 即可在 submit 时获取到表单中的数据,接下来我们补充一下基本的表单验证和错误提示:

    import React from "react";import { useForm } from "react-hook-form";function MyForm() {    const onSubmit = (data) => {      console.log(data);    };    const { register, handleSubmit, formState: { errors } } = useForm();    return (      <form onSubmit={handleSubmit(onSubmit)}>        <input {...register("firstName", { required: true })} />        {errors.firstName && <p>First name is required.</p>}        <input {...register("lastName", { required: true })} />        {errors.lastName && <p>Last name is required.</p>}        <button type="submit">Submit</button>      </form>    );}

    咱们再分析一下这段代码:

    • register 函数中可以指定表单输入组件的 验证规则 ,例如使用 required 规则来验证输入框的必填项。

    • 在表单提交处理函数中,可以调用 React Hook Form 提供的 handleSubmit 函数来自动执行表单验证,并返回验证结果。只有表单验证通过才会执行 onSubmit 方法。

    • 如果表单验证失败,可以使用 errors 对象来获取每个表单输入组件的验证错误信息,并在 UI 上显示错误提示。

    register 函数是用来注册表单输入组件的,当组件注册之后,React Hook Form 会自动收集该组件的值,并根据验证规则进行验证。 register 函数会返回一个对象,其中包含了一些属性和方法,例如:

    const { ref, onChange, onBlur, name } = register("firstName");

    ref 属性是一个引用,指向该输入组件的 DOM 元素,onChangeonBlur 是回调函数,用于处理该组件的值变化和失去焦点事件,name 是该组件的名称。

    register 函数内部会创建一个管理表单输入组件的对象,包含了该组件的名称、引用、验证规则等信息。同时,还会将该对象保存在 React Hook Form 内部的一个数据结构中。

    在表单提交时,React Hook Form 会遍历管理的所有表单输入组件,并收集它们的值,并根据其注册时定义的验证规则进行验证。

    到这里,一个最基本的表单验证及提交就已经实现了。当然,在实际开发中,表单之所以复杂是由于各种条件渲染及表单嵌套引起的,那么我们接下来再看看使用 React Hook Form 如何处理这些场景。

    表单嵌套

    还是一样,先看看示例:

    父级表单

    // ParentForm.jsximport React from "react";import { useForm, FormProvider } from "react-hook-form";import ChildForm from "./ChildForm";function ParentForm() {  const methods = useForm();  const { register, handleSubmit, formState: { errors } } = methods;  const onSubmit = (data) => {    console.log(data);  };  return (      <FormProvider {...methods}>        <form onSubmit={handleSubmit(onSubmit)}>          <h3>Parent Form</h3>          <label htmlFor="firstName">First Name</label>          <input {...register("firstName", { required: true })} />          {errors.firstName && <p>First name is required.</p>}          <label htmlFor="lastName">Last Name</label>          <input {...register("lastName", { required: true })} />          {errors.lastName && <p>Last name is required.</p>}          <ChildForm/>          <button type="submit">Submit</button>        </form>    </FormProvider>  );}export default ParentForm;

    子级表单

    import React from "react";import { useFormContext } from "react-hook-form";function ChildForm() {  const { register, errors } = useFormContext();  return (    <div>      <h3>Child Form</h3>      <label htmlFor="childFirstName">Child First Name</label>      <input {...register("child.firstName", { required: true })} />      {errors.child?.firstName && <p>Child first name is required.</p>}      <label htmlFor="childLastName">Child Last Name</label>      <input {...register("child.lastName", { required: true })} />      {errors.child?.lastName && <p>Child last name is required.</p>}    </div>  );}export default ChildForm;

    分析一下这两个组件的代码:

    • ParentForm 组件中,我们使用 useForm hook 来获取表单的注册函数、表单状态等信息,并使用 FormProvider 组件将其传递给所有的子组件。

    • ChildForm 组件中,我们使用了 useFormContext hook 来获取父表单的注册函数和表单状态。

    这里的两个表单组件间并不需要咱们去单独定义 props ,只需要将 useFormContextFormProvider 搭配使用,就可以将一个嵌套表单的逻辑分离成多个组件进行处理,且可以在父级组件提交时统一获取并处理数据。

    FormProvider 是 React Hook Form 提供的一个组件,用于在 React 组件树中向下传递 useForm hook 的实例。它创建了一个 React Context,并将 useForm hook 的实例作为 Context 的值,然后通过 Context.Provider 组件将这个值传递给所有子组件.

    useFormContext 则可以在子组件中获取到 FormProvider 提供的 useForm hook 的返回值。在使用 useFormContext 时,不需要手动使用 Context.Provider 将值传递给子组件,而是可以直接从 useFormContext 中获取,简化嵌套表单的代码逻辑。

    条件判断

    import React from "react";import { useForm } from "react-hook-form";function ExampleForm() {  const { register, handleSubmit, watch } = useForm();  const onSubmit = (data) => console.log(data);  return (    <form onSubmit={handleSubmit(onSubmit)}>      <label htmlFor="hasAge">Do you have an age?</label>      <select {...register("hasAge")}>        <option value="yes">Yes</option>        <option value="no">No</option>      </select>      {watch("hasAge") === "yes" && (        <>          <label htmlFor="age">Age</label>          <input {...register("age", { required: true, min: 18 })} />          {watch("age") && <p>You must be at least 18 years old.</p>}        </>      )}      <button type="submit">Submit</button>    </form>  );}export default ExampleForm;

    我们在 hasAge 输入框上使用了一个简单的条件渲染:只有当用户选择了 "Yes" 时,才会渲染 age 输入框。然后使用 watch 函数来监听输入框的值,并在输入的值小于 18 时显示相应的错误信息。

    watch 函数用来监听指定的输入并返回它们的值。在渲染输入值和进行条件渲染时经常用到。

    表单列表

    import React from "react";import { useForm, useFieldArray } from "react-hook-form";function ListForm() {  const { register, control, handleSubmit } = useForm({    defaultValues: {      list: [{ name: "" }, { name: "" }, { name: "" }]    }  });  const { fields, append, remove } = useFieldArray({    control,    name: "list"  });  const onSubmit = (data) => console.log(data);  return (    <form onSubmit={handleSubmit(onSubmit)}>      {fields.map((field, index) => (        <div key={field.id}>          <input            {...register(`list.${index}.name`, {              required: "This field is required"            })}            defaultValue={field.name}          />          <button type="button" onClick={() => remove(index)}>            Remove          </button>        </div>      ))}      <button type="button" onClick={() => append({ name: "" })}>        Add Item      </button>      <button type="submit">Submit</button>    </form>  );}export default ListForm;

    分析一下上边这段代码:

    • 在这个示例中,我们使用了 useFormuseFieldArray hook 来处理一个表单列表。其中 list 属性是一个包含 3 个空对象的数组

    • 使用 fields.map 方法遍历 fields 数组,渲染出每一个列表项。

    • 使用 remove 方法为每个列表项添加了一个 "Remove" 按钮,使得用户可以删除不需要的列表项。我们还使用 append 方法添加了一个 "Add Item" 按钮,可以添加新的列表项。

    这段代码的核心就是 useFieldArray,它专门用于处理表单列表的场景,使用时我们将 useForm 返回的 control 传入 useFieldArray hook 中,并为这个列表定义一个名字,hook 会为我们返回一些操作列表的方法,在遍历渲染列表时,我们将每一个子项单独进行注册就可以实现表单列表的动态数据更改了。

    需要注意的是,当使用 useFieldArray 处理表单中的数组字段时,每个字段都必须有一个 唯一的 key 值,这样才能正确地进行数组的添加、删除、更新等操作。如果数组中的字段没有 key 值,useFieldArray 会自动为每个字段生成一个随机的 key 值。

    在内部实现上,useFieldArray 使用了 useFormContext 将 FormProvider 提供的 registerunregistersetValue 函数传递给了 useFieldArray,然后在 useFieldArray 内部维护一个数组 state,保存当前的数组值和对数组的操作。

    第三方组件

    当需要与第三方UI组件(如<DatePicker /><Select /><Slider />等)集成时,如果使用register 注册这些第三方UI组件,可能会遇到如无法正确更新表单数据、错误处理、性能差等问题。

    因此,使用Controller 是一种更好的解决方案,可以将表单数据与 React Hook Form 状态管理集成在一起,并使用render 函数来直接渲染第三方UI组件。下面放个例子:

    import React from "react";import { useForm, Controller } from "react-hook-form";import { TextField, Button } from "@material-ui/core";function ControllerForm() {  const { control, handleSubmit } = useForm();  const onSubmit = (data) =&gt; console.log(data);  return (    &lt;form onSubmit={handleSubmit(onSubmit)}&gt;      &lt;Controller        name="firstName"        control={control}        defaultValue=""        rules={{ required: true }}        render={({ field }) =&gt; (          &lt;TextField label="First Name" {...field} /&gt;        )}      /&gt;      &lt;Controller        name="lastName"        control={control}        defaultValue=""        rules={{ required: true }}        render={({ field }) =&gt; (          &lt;TextField label="Last Name" {...field} /&gt;        )}      /&gt;      &lt;Button type="submit" variant="contained" color="primary"&gt;        Submit      &lt;/Button&gt;    &lt;/form&gt;  );}export default ControllerForm;

    control 是一个对象,它提供了一些方法和属性,通过使用 control,我们可以将 React Hook Form 中的数据与实际渲染的表单组件进行绑定,从而让 React Hook Form 管理表单中所有的输入和校验逻辑。

    field<Controller> 组件通过 render 回调函数传递给其子组件的一个对象,field 对象中包含了一些属性,如 valueonChangeonBlur 等,这些属性传递给子组件,用于设置和更新表单控件的值,以及处理表单控件的事件,如用户输入、聚焦、失焦等。

    Controller的好处是可以将表单数据和表单状态统一管理,同时避免了对表单数据的手动处理。此外,它还可以优化表单的渲染性能,并提供更好的错误处理机制,因为它可以自动处理错误消息和验证规则。

    typescript 支持

    React Hook Form 提供了完整的 TypeScript 支持:

    import React from "react";import { useForm, SubmitHandler } from "react-hook-form";type FormValues = {  firstName: string;  lastName: string;  age: number;};function MyForm() {  const {    register,    handleSubmit,    formState: { errors },  } = useForm<FormValues>();  const onSubmit: SubmitHandler<FormValues> = (data) => console.log(data);  return (    <form onSubmit={handleSubmit(onSubmit)}>      <input {...register("firstName", { required: true })} />      {errors.firstName && <span>This field is required</span>}      <input {...register("lastName", { required: true })} />      {errors.lastName && <span>This field is required</span>}      <input {...register("age", { required: true, min: 18 })} />      {errors.age && (        <span>          {errors.age.type === "required"            ? "This field is required"            : "You must be at least 18 years old"}        </span>      )}      <button type="submit">Submit</button>    </form>  );}

    我们使用 FormValues 类型定义表单数据类型,并在 useForm 钩子中使用 FormValues 泛型接口。这使得我们可以在注册表单控件时提供正确的类型定义,并在 handleSubmit 函数中提供正确的表单数据类型。还可以使用泛型来定义错误消息的类型,可以用于准确地描述表单控件的错误状态,并提供适当的错误消息。提高代码的可读性和可维护性。

    以上就是关于“React Hook Form优雅处理表单使用的方法是什么”这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注编程网精选频道。

    --结束END--

    本文标题: React Hook Form优雅处理表单使用的方法是什么

    本文链接: https://www.lsjlt.com/news/351318.html(转载时请注明来源链接)

    有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

    本篇文章演示代码以及资料文档资料下载

    下载Word文档到电脑,方便收藏和打印~

    下载Word文档
    猜你喜欢
    • React Hook Form优雅处理表单使用的方法是什么
      这篇“React Hook Form优雅处理表单使用的方法是什么”文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看...
      99+
      2023-07-05
    • ReactHookForm优雅处理表单使用指南
      目录受控组件与非受控组件受控组件非受控组件为什么需要非受控组件React Hook Form 是什么?React Hook Form 的使用姿势数据收集表单嵌套条件判断表单列表第三方...
      99+
      2023-03-10
      React Hook Form处理表单 React Hook Form
    • Python中优雅处理JSON文件的方法是什么
      这篇文章给大家介绍Python中优雅处理JSON文件的方法是什么,内容非常详细,感兴趣的小伙伴们可以参考借鉴,希望对大家能有所帮助。1. 引言我们将学习如何使用Python读取、解析和编写JSON文件。我们将讨论如何最好地处理简单的JSON...
      99+
      2023-06-22
    • 怎么优雅的使用Angular表单验证
      本篇内容主要讲解“怎么优雅的使用Angular表单验证”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“怎么优雅的使用Angular表单验证”吧!说到表单,我认为一...
      99+
      2024-04-02
    • 使用js提交form表单的两种方法
      使用JavaScript提交表单有两种常见的方法:1. 使用`submit()`方法:可以在表单元素上调用`submit()`方法来...
      99+
      2023-09-17
      js
    • Swift Hook的虚函数表的使用原理是什么
      这篇文章主要介绍“Swift Hook的虚函数表的使用原理是什么”,在日常操作中,相信很多人在Swift Hook的虚函数表的使用原理是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望...
      99+
      2024-04-02
    • unplugin-svg-component优雅使用svg图标的方法是什么
      这篇文章主要介绍了unplugin-svg-component优雅使用svg图标的方法是什么的相关知识,内容详细易懂,操作简单快捷,具有一定借鉴价值,相信大家阅读完这篇unplugin-svg-component优雅使用svg图标的方法是什...
      99+
      2023-07-05
    • 如何使用Ajax方法实现Form表单的提交
      这篇文章主要介绍了如何使用Ajax方法实现Form表单的提交,具有一定借鉴价值,感兴趣的朋友可以参考下,希望大家阅读完这篇文章之后大有收获,下面让小编带着大家一起了解一下。常见的form表单提交方式<...
      99+
      2024-04-02
    • PHP表单的应用方法是什么
      PHP表单的应用方法有以下几种:1. 提交表单数据到服务器:用户在表单中填写完数据后,点击提交按钮,表单数据会被发送到服务器,服务器...
      99+
      2023-10-12
      PHP
    • Python中使用Numpy优化文件处理的方法是什么?
      文件处理是编程中常见的任务之一,而Python中的Numpy库提供了一些优化文件处理的方法。本文将介绍如何使用Numpy库来优化文件处理,并通过演示代码来说明其实现方法。 一、Numpy库简介 Numpy是Python中一个重要的科学计算...
      99+
      2023-06-01
      numpy django 文件
    • 使用AjaxSubmit()方法怎么实现Form提交表单后回调功能
      今天就跟大家聊聊有关使用AjaxSubmit()方法怎么实现Form提交表单后回调功能,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。2.    ...
      99+
      2023-06-08
    • MySQL表结构优化管理的方法是什么
      MySQL表结构优化管理的方法包括以下几个方面: 正确选择数据类型:选择适当的数据类型可以减小存储空间的占用,并提高查询和索引的...
      99+
      2023-10-24
      MySQL
    • HTML表单制作的方法是什么
      HTML表单制作的方法有以下几个步骤:1. 创建表单元素:使用``标签创建表单元素,并设置`action`属性指定数据提交的URL地...
      99+
      2023-09-22
      HTML
    • django实现表单的方法是什么
      在Django中,可以通过以下步骤实现表单:1. 创建一个继承自`forms.Form`的表单类。在表单类中,定义需要的字段,并为每...
      99+
      2023-09-26
      django
    • php提交表单的方法是什么
      本篇内容主要讲解“php提交表单的方法是什么”,感兴趣的朋友不妨来看看。本文介绍的方法操作简单快捷,实用性强。下面就让小编来带大家学习“php提交表单的方法是什么”吧!php表单提交方法:1、使用PHP $_REQUEST收集HTML表单提...
      99+
      2023-06-20
    • React各种状态管理器的原理及使用方法是什么
      今天就跟大家聊聊有关React各种状态管理器的原理及使用方法是什么,可能很多人都不太了解,为了让大家更加了解,小编给大家总结了以下内容,希望大家根据这篇文章可以有所收获。首先我们要先知道什么是状态管理器,这玩意是干啥的?当我们在多个页面中使...
      99+
      2023-06-25
    • Component的React表格控件用法是什么
      这篇文章主要介绍“Component的React表格控件用法是什么”,在日常操作中,相信很多人在Component的React表格控件用法是什么问题上存在疑惑,小编查阅了各式资料,整理出简单好用的操作方法,希望对大家解答”Component...
      99+
      2023-06-04
    • php购物车订单处理的方法是什么
      在PHP中,处理购物车订单通常需要执行以下步骤:1. 创建一个包含商品信息的购物车数组或使用数据库存储购物车信息。2. 当用户添加商...
      99+
      2023-08-25
      php
    • Vue3 echarts组件化及使用hook进行resize的方法是什么
      echarts组件化及使用hook进行resizehook 本质是一个函数,把setup函数中使用的 Composition API 进行了封装组件化echarts实例<template> <div ref="...
      99+
      2023-05-23
      Vue3 hook echarts
    • React 中使用 RxJS 优化数据流的处理方案
      目录正文一般来说,处理组件中的数据流无非三种情况:下面我们看一个很简单的例子:那么,问题来了,使用数据流的方式来处理数据有什么好处呢?正文 现在我们比较熟悉的是使用 functio...
      99+
      2023-02-17
      React RxJS 优化数据流 React RxJS
    软考高级职称资格查询
    编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
    • 官方手机版

    • 微信公众号

    • 商务合作