用于构建表单和调查的 React 库

**由侯赛因·阿里夫✏️撰写**

虽然在 React 中构建表单很简单,但管理它们却很复杂。例如,如果不依赖表单库,开发人员必须:

  • 处理验证:例如,对于每个 onChange 或 onSubmit 事件,我们必须告诉 React 检查某个字段是否符合给定的条件
  • 处理提交:如果用户想要注册我们的应用程序,我们必须检查他们的电子邮件是否存在于数据库中,然后从那里处理情况
  • 考虑性能:有时,在表单中渲染复杂的组件或使用复杂的验证逻辑可能会导致性能下降
  • 为了缓解这些挑战,我们可以使用表单库来为我们处理大部分繁重的工作。在本文中,我们将介绍 React 生态系统中一些流行的表单库:

  • SurveyJS:一个表单构建库,允许开发人员呈现 JSON 表单和调查。除了 React,它还包括 Angular、Vue、jQuery 和 Knockout 的集成
  • React Hook Form:一个无头库,允许开发人员处理表单而无需编写太多样板代码。此库还支持 React Native
  • rc-field-form:与 React Hook Form 一样,rc-field-form 允许用户在 Web 和移动平台上管理表单。此外,它注重性能和效率。这对于想要构建轻量级应用程序的开发人员特别有用
  • Tanstack Form:由 TanStack 团队构建的轻量级表单管理库。此外,它还支持许多其他库,如 Vue、Angular、Lit 等
  • 现在我们已经简单介绍了一些 React 表单库,让我们开始探索吧!

    设置我们的 React 项目

    在编写代码之前,我们必须先搭建 React 项目。为此,请在终端中运行以下命令:

    #initialize React project with Typescript:
    npm create vite@latest form-libraries --template react-ts
    cd form-libraries
    npm install #install the needed packages to run the project.

    React 表单库:SurveyJS

    如前所述,SurveyJS 是一个用于构建多页表单和调查的库。它支持多种功能,包括:

  • 本地化:SurveyJS 支持字符串的自动翻译,因此无需手动输入
  • 可视化表单构建:使没有编码专业知识的用户能够通过可视化界面创建表单
  • 可定制的预样式组件:提供一系列预先设计的组件,可以轻松定制以满足特定的设计需求
  • 要将 SurveyJS 包含在我们的项目中,请通过 npm 安装它:

    npm install survey-react-ui --save

    此代码块展示了 SurveyJS 库的实际作用:

    import "survey-core/defaultV2.min.css";
    import { Model, SurveyModel } from "survey-core";
    import { Survey } from "survey-react-ui";
    import { useCallback } from "react";
    
    export function SurveyExample() {
      //create our schema for our form:
      const surveyJson = {
        elements: [
          //configure our fields
          {
            name: "FirstName",
            title: "Enter your first name:",
            type: "text",
          },
          {
            name: "LastName",
            title: "Enter your last name:",
            type: "text",
          },
        ],
      };
      //feed the schema into the model
      const survey = new Model(surveyJson);
      //handler function that runs when the user submits the form
      const surveyComplete = useCallback((survey: SurveyModel) => {
        const userOutput = survey.data;
        console.log(userOutput);
      }, []);
      //attach this handler to the form
      survey.onComplete.add(surveyComplete);
      return (
        
    {/*Finally, pass our model and render the form*/}
    ); } //don't forget to render this component in App.tsx!

    在上面的代码片段中:

  • 首先,我们声明了 surveyJson 变量,它将是我们表单的架构。该架构将传递呈现表单所需的数据。
  • 然后,我们初始化 surveyComplete 处理程序。此函数将在用户提交表单时运行。在本例中,我们只是将用户的输入记录到控制台
  • 最后,我们将模型传递给 Survey 组件,以将表单呈现到 DOM
  • 让我们测试一下!要运行该项目,请输入以下命令:

    npm run dev

    React Hook 表单

    React Hook Form 是一个无依赖的库,可以实现高效的表单验证。它具有以下特点:

  • 订阅:React Hook Form 允许开发人员查看单个输入,而无需重新渲染父组件
  • 重新渲染隔离:该库使用性能技巧来防止其应用程序中不必要的重新渲染
  • Headless:这意味着开发人员可以自由选择自己喜欢的组件库与 React Hook Form 一起使用
  • 基于 Hook 的 API:允许组件相对轻松地访问和操作本地状态。这也表明该库遵循了 React 的最佳实践
  • 与往常一样,第一步是在你的项目中安装 React Hook Form:

    npm install react-hook-form

    下面是一段演示 React Hook Form 中验证的代码:

    import { useState } from "react";
    import { useForm, SubmitHandler } from "react-hook-form";
    
    type Inputs = {
      twice: boolean;
      newjeans: boolean;
      name: string;
    };
    export default function ReactHookForm() {
      const {
        register,
        handleSubmit,
        watch,
        formState: { errors },
      } = useForm({ defaultValues: { twice: true, name: "LogRocket" } });
      const [output, setOutput] = useState();
      const onSubmit: SubmitHandler = (data) => setOutput(data);
      return (
        

    Your favorite group?

    {/* register your input into the hook by invoking the "register" function */} {/* include validation with required or other standard HTML validation rules */} {/* errors will return when field validation fails */}

    {output?.newjeans && "newjeans was selected"}

    {output?.twice && "twice was selected"}

    Name: {output?.name}

    ); }

    让我们逐一分解这段代码:

  • 首先,我们创建一个 Inputs 类型,其中包含我们想要填充的字段
  • 然后,我们使用 useForm Hook,并通过 defaultValues 属性传入字段和默认值
  • 之后,我们声明了 onSubmit 处理程序,它将更新名为 output 的 Hook。稍后我们将在此代码中将 output Hook 渲染到 DOM
  • 接下来,我们在输入组件上使用 register 函数。这告诉 React 我们要将输入与 useForm Hook 连接起来
  • 最后,React 会根据用户的输入显示输出 Hook 的值
  • 就这样!让我们测试一下 React Hook Form:

    rc-字段形式

    与 React Hook Form 类似,rc-field-form 是另一个注重性能和易用性的 React 表单库。

    首先,只需安装依赖项,如下所示:

    npm install rc-field-form

    此代码片段展示了如何通过 rc-field-form 库在文本字段上实现异步验证:

    import Form, { Field } from "rc-field-form";
    
    const Input = ({ value = "", ...props }) => ;
    export const RCFieldFormExample = () => {
      return (
        
    { console.log("Finish:", values); }} >
    ); };

    以下是我们计划的简要说明:

  • 我们渲染了 Form 组件并定义了 onFinish 处理程序。这将告诉 React 在提交后应将用户的输入输出到控制台
  • 然后,我们渲染了两个 Field 组件:一个用于用户名,另一个用于密码
  • 然后,为了进行验证,我们在用户名字段中配置了规则属性。在这里,我们指示库,如果用户名字段设置为 Log,则必须显示错误消息
  • 以下是代码的输出:

    太棒了!如你所见,我们的代码可以正常工作!

    Tanstack 与 Zod 组建

    Tanstack 团队无需介绍。最近,他们将 TanStack Form 引入了他们的高质量实用程序库。尽管仍处于测试阶段,但该库包含一系列详尽的功能,包括:

  • 无头:与 React Hook Form 一样,TanStack Form 处理所有逻辑,开发人员可以使用他们选择的组件库
  • 异步验证
  • 轻的
  • 基于钩子的设计
  • 与往常一样,使用库的第一步是安装它:

    #react-form: to render and build forms
    #zod-form-adapter and zod: For validation purposes.
    npm i @tanstack/react-form @tanstack/zod-form-adapter zod

    接下来,让我们构建一个在发生验证错误时通知用户的组件:

    import type { FieldApi } from "@tanstack/react-form";
    
    function FieldInfo({ field }: { field: FieldApi }) {
      return (
        <>
          {/*If error occurs, display it. */}
          {field.state.meta.isTouched && field.state.meta.errors.length ? (
            {field.state.meta.errors.join(",")}
          ) : null}
          {field.state.meta.isValidating ? "Validating..." : null}
        
      );
    }

    在这里,我们创建了一个名为“FieldInfo”的组件,它将检查用户是否未通过任何验证检查。如果满足此条件,它将在页面上显示错误。

    最后,使用 Tanstack Form 编写以下代码块用于表单渲染和验证:

    import { useForm } from "@tanstack/react-form";
    import { zodValidator } from "@tanstack/zod-form-adapter";
    import { z } from "zod";
    
    //step 1: define our schema and each field's requirements
    const userSchema = z.object({
      //if the user's name is Log, display an error.
      firstName: z.string().refine((val) => val !== "Log", {
        message: "[Form] First name cannot be Log!",
      }),
      //the user's age should be atleast 18.
      age: z.coerce.number().min(18, "Need to be an adult!"),
    });
    
    type User = z.infer;
    export default function TanstackFormExample() {
      //use the useForm hook and define our default values.
      const form = useForm({
        defaultValues: {
          firstName: "",
          age: 0,
        } as User,
        onSubmit: async ({ value }) => {
          console.log(value);
        },
        //configure our validation
        validatorAdapter: zodValidator(),
        validators: {
          onSubmit: userSchema,
        },
      });
      return (
        
    { e.preventDefault(); e.stopPropagation(); form.handleSubmit(); }} >
    {/*Create our fields and inputs*/} { return ( <> field.handleChange(e.target.value)} /> ); }} />
    {/*Second input for the user's age*/} ( <> field.handleChange(e.target.valueAsNumber)} /> )} />
    {/*This component will run when the form's state changes*/} { return state; }} children={(state) => { return ( //check if the user can submit the form: ); }} />
    ); }

    这段代码乍一看可能让人望而生畏,但其中大部分都是库运行所需的样板。解释在代码注释中。

    运行时,TanStack Form 输出应如下所示:

    比较我们介绍过的 React 表单库

    下表比较了本指南中介绍的库:

    在本文中,我们了解了 React 中的几个表单构建库。此外,我们还介绍了如何在这些库中对表单执行渲染和验证。在我的业余项目中,我使用 React Hook Form,因为它提供了可靠且高性能的解决方案以及用户友好的开发人员体验。这是本文的源代码。

    当然,根据项目的需求,用户也可以选择 Formik 或 Ant Design 等库进行表单管理。

    感谢您的阅读!

    几分钟内即可设置 LogRocket 的现代 React 错误跟踪:

  • 访问 https://logrocket.com/signup/ 获取应用程序 ID。
  • 通过 NPM 或脚本标签安装 LogRocket。LogRocket.init() 必须在客户端调用,而不是服务器端。
  • 新版本:

    $ npm i --save logrocket 
    
    // Code:
    
    import LogRocket from 'logrocket'; 
    LogRocket.init('app/id');

    脚本标记:

    Add to your HTML:
    
    
    
  • (可选)安装插件以便与您的堆栈进行更深入的集成:
  • Redux 中间件
  • ngrx 中间件
  • Vuex 插件
  • 立即开始