React表单:formik、final-form和react-hook-form

alt

表单无处不在,它是每个网站的必备部分。在用React构建web应用时,处理表单是不可避免的。

你可以选择自己的方式来处理,或者选择社区中现成的库。然而,当你选择一个第三方库时,你会立即面临一个问题:有太多的库可供选择。

选择一个库是一件棘手的事情,随意选择一个GitHub上星标多的库并不总是明智的。你肯定需要阅读文档、代码示例,并多次尝试,才能确定这是你想要用于自己项目的库。

对于处理表单,我们有以下选择:

库名称GitHub星标下载次数体积
formik23.4K868k/周7.22 kB
final-form2.5K222k/周5.1 kB
react-Form1.9K12k/周4.3 kB
react-hook-form12.5K270k/周8.67 kB
redux-form12.3K389k/周26.4 kB

在这里中,我们将比较下载次数最多的三个库:formik、final-form和react-hook-form

对于redux-form,我们可以忽略它,毕竟已经是2020年了,没有人会再把每个输入的keystore存储在Redux中,这极其影响性能。而且该库的作者也建议大家转向使用final-form。

使用方式比较

Formik

在GitHub星标数量、下载次数方面,formik是使用人数最多的库,星标最多,下载次数也最多。

老实说,我不喜欢formik的口号“无需含泪构建表单”,因为在React中构建表单和验证从未过于复杂。

使用formik,你需要在组件的render部分直接渲染Formik的Form组件:

import React from "react";
import { Formik } from "formik";

const Basic = () => (
  <div>
    <h1>在你的应用任何地方!</h1>
    <Formik
      initialValues={{ email: "", password: "" }}
      validate={(values) =>
 {
        const errors = {};
        if (!values.email) {
          errors.email = "必填";
        } else if (
          !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
        ) {
          errors.email = "无效的电子邮件地址";
        }
        return errors;
      }}
      onSubmit={(values, { setSubmitting }) => {
        setTimeout(() => {
          alert(JSON.stringify(values, null, 2));
          setSubmitting(false);
        }, 400);
      }}
    >
      {({
        values,
        errors,
        touched,
        handleChange,
        handleBlur,
        handleSubmit,
        isSubmitting,
        /* 和其他好东西 */
      }) => (
        <form onSubmit={handleSubmit}>
          <input
            type="email"
            name="email"
            onChange={handleChange}
            onBlur={handleBlur}
            value={values.email}
          />

          {errors.email && touched.email && errors.email}
          <input
            type="password"
            name="password"
            onChange={handleChange}
            onBlur={handleBlur}
            value={values.password}
          />

          {errors.password && touched.password && errors.password}
          <button type="submit" disabled={isSubmitting}>
            提交
          </button>
        </form>
      )}
    </Formik>
  </div>

);

export default Basic;

上述代码相当长,并且有一些缺点:

  • 你必须在组件内直接渲染Formik组件,这使得你的渲染部分相对混乱。
  • 你必须手动将handleChange、handleBlur等函数映射到输入元素上,这项工作相当耗时。不过,你可以使用formik的Field或ErrorMessage组件来节省时间。
  • Formik没有内置验证,你需要自己编写函数来验证表单值,或者使用像yup这样的库来支持验证。
  • Formik不支持完整的hook,尽管你可以使用useFormik hook,但使用这个hook时,Field、ErrorMessage、FieldArray等组件将无法工作。

Final-Form

final-form由redux-form的作者编写,因此相当有名。

创建一个final-form表单如下:

import React from "react";
import { render } from "react-dom";
import Styles from "./Styles";
import { Form, Field } from "react-final-form";

const sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));

const onSubmit = async (values) => {
  await sleep(300);
  window.alert(JSON.stringify(values, 02));
};

const App = () => (
  <Styles>
    <h1>React Final Form示例</h1>
    <h2>密码/确认验证</h2>
    <a
      href="https://final-form.org/react"
      target="_blank"
      rel="noopener noreferrer"
    >

      阅读文档
    </a>
    <Form
      onSubmit={onSubmit}
      validate={(values) =>
 {
        const errors = {};
        if (!values.username) {
          errors.username = "必填";
        }
        if (!values.password) {
          errors.password = "必填";
        }
        if (!values.confirm) {
          errors.confirm = "必填";
        } else if (values.confirm !== values.password) {
          errors.confirm = "必须匹配";
        }
        return errors;
      }}
      render={({ handleSubmit, form, submitting, pristine, values }) => (
        <form onSubmit={handleSubmit}>
          <Field name="username">
            {({ input, meta }) => (
              <div>
                <label>用户名</label>
                <input {...inputtype="text" placeholder="用户名" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>
          <Field name="password">
            {({ input, meta }) => (
              <div>
                <label>密码</label>
                <input {...inputtype="password" placeholder="密码" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>
          <Field name="confirm">
            {({ input, meta }) => (
              <div>
                <label>确认</label>
                <input {...inputtype="password" placeholder="确认" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>
          <div className="buttons">
            <button type="submit" disabled={submitting}>
              提交
            </button>
            <button
              type="button"
              onClick={form.reset}
              disabled={submitting || pristine}
            >

              重置
            </button>
          </div>
          <pre>{JSON.stringify(values, 0, 2)}</pre>
        </form>
      )}
    />
  </Styles>

);

render(<App />document.getElementById("root"));

在我看来,使用final-form的方式与formik类似,但在渲染Form组件后,你必须使用Field组件来传递final-form的props到你的输入元素。

因此,将final-form与react-select等其他React组件集成可能会有些困难。

此外,final-form没有内置验证,你必须自己编写函数来验证表单数据。

Final-form也不支持joi或yup,你必须自己找到方法让final-form能够使用yup,如下所示:链接

React-Hook-Form

第一次看到是在reddit上(https://www.reddit.com/r/reactjs)上,当时项目也需要处理表单,我自己写表单非常耗时,所以我决定尝试使用react-hook-form。

使用react-hook-form的方式如下:

import React from "react";
import { useForm } from "react-hook-form";

export default function App({
  const { register, handleSubmit, watch, errors } = useForm();
  const onSubmit = data => console.log(data);

  console.log(watch("example")); // 通过传递名称来监视输入值

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input name="example" defaultValue="test" ref={register} />

      <input name="exampleRequired" ref={register({ required: true })} />
      {errors.exampleRequired && <span>这个字段是必填的</span>}

      <input type="submit" />
    </form>

  );
}

在这三个库中,我认为react-hook-form是最容易使用的。你只需要使用useForm来创建表单,同时使用register来将输入注册到react-hook-form。

当你将react-hook-form与react-select等其他表单输入库一起使用时,也非常简单,你可以使用setValue函数将该组件的值传递给react-hook-form。

React-hook-form还提供了一些内置函数来验证表单内容:

import React from "react";
import { useForm } from "react-hook-form";

export default function App({
  const { register, handleSubmit } = useForm();
  const onSubmit= data => console.log(data);

  return (
    <form onSubmit={handleSubmit(onSubmit)}>
      <input
        name="firstName"
        ref={register({ required: truemaxLength: 20 })}
      />

      <input
        name="lastName"
        ref={register({ pattern: /^[A-Za-z]+$/i })}
      />

      <input
        name="age"
        type="number"
        ref={register({ min: 18max: 99 })}
      />

      <input type="submit" />
    </form>

  );
}

同时,你也可以使用像yup这样的库来验证表单内容。

react-hook-form 基于非受控组件,这意味着你不需要通过状态和 onChange 事件来更新输入值。相反,你只需要设置 defaultValue。

根据react-hook-form的官网,由于它限制了不必要的组件重新渲染次数,并且具有最低的挂载时间,因此它具有最佳的性能。

另外它体积小(压缩后仅8.6 kB),而且没有外部依赖,使得应用的加载速度更快,同时也减少了项目的复杂性。

结论

react-hook-form是目前最容易使用的库,同时它的文档也非常好。在我看来,react-hook-form唯一的限制是它只能与函数组件一起使用。因此,如果你的项目仍然在使用旧版本的React,那么你就无法使用它。

本文由 mdnice 多平台发布

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/433735.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Spring Boot 学习之路 -- 配置项目

前言 最近因为业务需要&#xff0c;被拉去研究后端的项目&#xff0c;代码框架基于 Spring Boot&#xff0c;对我来说完全小白&#xff0c;需要重新学习研究…出于个人习惯&#xff0c;会以 Blog 文章的方式做一些记录&#xff0c;文章内容基本来源于「 Spring Boot 从入门到精…

SpringMVC5-域对象共享数据

目录 使用ServletAPI向request域对象共享数据 使用ModelAndView向request域对象共享数据 使用Model向request域对象共享数据 使用map向request域对象共享数据 使用ModelMap向request域对象共享数据 Model、ModelMap、Map的关系 向session域共享数据 向application域共享…

SQLite3模块使用详解

目录 一、引言 1.1 SQLite3 简介 1.2 Python sqlite3 模块 二、连接数据库 2.1 导入 sqlite3 模块 2.2 连接数据库 2.3 创建游标对象 三、执行 SQL 语句 3.1 创建表 3.2 插入数据 3.3 查询数据 3.4 更新数据 3.5 删除数据 四、处理查询结果 4.1 fetchall() 4.2…

探探Java与python中的闭包

说在前面&#xff1a;在计算机科学中&#xff0c;闭包是指一个函数以及其引用的周围环境&#xff08;变量&#xff09;所组成的整体。简单来说&#xff0c;闭包允许一个函数访问并操作其外部函数作用域中的变量&#xff0c;即使外部函数已经执行完毕。 Java函数式编程—闭包&am…

C++map与set

文章目录 前言一、map和set基础知识二、set与map使用示例1.set去重操作2.map字典统计 总结 前言 本章主要介绍map和set的基本知识与用法。 一、map和set基础知识 map与set属于STL的一部分&#xff0c;他们底层都是是同红黑树来实现的。 ①set常见用途是去重 &#xff0c;set不…

【Java】包装类【主线学习笔记】

文章目录 前言包装类基本数据类型与包装类之间的转换基本数据类型转换为包装类可以通过以下几种方式&#xff1a;包装类转换为基本数据类型可以通过以下几种方式&#xff1a;初始化值不同与String之间的转换 前言 Java是一门功能强大且广泛应用的编程语言&#xff0c;具有跨平台…

“数字武当”项目荣获2024年“数据要素×”大赛湖北分赛文化旅游赛道一等奖

9月26日&#xff0c;由国家数据局、湖北省人民政府指导的首届湖北省数据要素创新大会暨2024年“数据要素”大赛湖北分赛颁奖仪式在湖北武汉举行。由大势智慧联合武当山文化旅游发展集团有限公司参报的武当山“数字武当”项目&#xff0c;荣获文化旅游赛道一等奖。 据悉&#x…

在系统开发中提升 Excel 数据导出一致性与可维护性的统一规范与最佳实践

背景&#xff1a; 在系统开发过程中&#xff0c;数据导出为 Excel 格式是一个常见的需求。然而&#xff0c;由于各个开发人员的编码习惯和实现方式不同&#xff0c;导致导出代码风格不一。有的人使用第三方库&#xff0c;有的人则自定义实现。这种多样化不仅影响了代码的一致性…

【笔记】X射线物理基础

一、X射线衍射分析简史 1895年X射线发现 1896 年 2 月对骨折的观察&#xff1a;G.和 E. Frost是第一个使用 X 射线进行医疗用途 1897 年法国海关官员的行李扫描。 X射线衍射理论1 X射线衍射理论2 元素的特征X射线 X射线光电子的应用 电磁波的粒子属性 X射线层析成像法 X-ray…

结构设计模式 -装饰器设计模式 - JAVA

装饰器设计模式 一. 介绍二. 代码示例2.1 抽象构件&#xff08;Component&#xff09;角色2.2 具体构件&#xff08;Concrete Component&#xff09;角色2.3 装饰&#xff08;Decorator&#xff09;角色2.4 具体装饰&#xff08;Concrete Decorator&#xff09;角色2.5 测试 结…

蓝桥杯--STM32G431RBT6(TIM定时器的输出频率和占空比,含详细原理介绍和使用方法)

目录 一、前言 二、代码 实现功能&#xff1a;​编辑 按如图配置 定义变量 编写执行代码 显示在LCD上 加入按键效果 三、效果展示 四、代码开源 一、前言 ARR 即自动重装载值&#xff08;Auto Reload Register&#xff09;。相当于一个水杯&#xff0c;水杯容量&am…

SpringCloud-Netflix第一代微服务快速入门

1.springCloud常用组件 Netflix Eureka 当我们的微服务过多的时候&#xff0c;管理服务的通信地址是一个非常麻烦的事情&#xff0c;Eureka就是用来管理微服务的通信地址清单的&#xff0c;有了Eureka之后我们通过服务的名字就能实现服务的调用。 Netflix Ribbon\Feign : 客…

性能测试常见故障和解决思路详解

&#x1f345; 点击文末小卡片&#xff0c;免费获取软件测试全套资料&#xff0c;资料在手&#xff0c;涨薪更快 一、性能问题分析流程 1、查看服务器的CPU、内存 、负载等情况&#xff0c;包括应用服务器和数据库服务器 2、查看数据库健康状态&#xff0c;数据库死锁、连…

【Java】单元测试【主线学习笔记】

文章目录 前言测试分类JUnit单元测试介绍编写单元测试方法的条件IDEA中简易使用JUnit 前言 Java是一门功能强大且广泛应用的编程语言&#xff0c;具有跨平台性和高效的执行速度&#xff0c;广受开发者喜爱。在接下来的学习过程中&#xff0c;我将记录学习过程中的基础语法、框架…

我们是向量数据库的领军企业,我们只招TOP人才

我们是全球领先的向量数据库企业&#xff0c;业务正在快速发展&#xff0c;现开放大量岗位&#xff1a; 前端、产品经理、数据库开发工程师、C、数据库运维、数据库测试…… 我们招聘的唯一目标&#xff0c;寻找 TOP人才&#xff01; 如果你已经有丰富的经验&#xff0c;那么加…

【友元补充】【动态链接补充】

友元 友元的目的是让一个函数或者类&#xff0c;访问另一个类中的私有成员。 有缘的关键字friend是一个修饰符。 友元分为友元类和友元函数 1.全局函数作友元 2.类作友元 3.类的一个成员函数作友元 好处&#xff1a;可以通过友元在类外访问类内的私有和受保护类型的成员 坏处…

CC面试准备

半导体基础 半导体是介于导体和绝缘体之间的一种介质&#xff0c;在不同条件下表现出不同的导电性或者不导电特性&#xff0c; 电子半导体器件材料大部分为硅&#xff0c;锗等元素 本征半导体&#xff1a;完全不含杂质的纯净半导体&#xff0c;因为不含杂质&#xff0c;其中…

使用API有效率地管理Dynadot域名,设置域名服务器(NS)

前言 Dynadot是通过ICANN认证的域名注册商&#xff0c;自2002年成立以来&#xff0c;服务于全球108个国家和地区的客户&#xff0c;为数以万计的客户提供简洁&#xff0c;优惠&#xff0c;安全的域名注册以及管理服务。 Dynadot平台操作教程索引&#xff08;包括域名邮箱&…

OCR识别系统 YOLOv8 +Paddle 方案落地

YOLOv8 PaddleOCR 技术方案落地 Yolov8相关文档Step 1 证件模型的训练Step 2 Yolov8进行图片推理Step 3 PaddleOCR进行识别Step 4 整合Yolov8 PaddleOCR 进行OCR Yolov8相关文档 《yolov8 官方网站》 《Yolov8 保姆级别安装》 Ultralytics YOLOv8 是一款尖端的、最先进的 (S…

【项目经验分享】深度学习自然语言处理技术毕业设计项目案例定制

以下毕业设计是与深度学习自然语言处理&#xff08;NLP&#xff09;相关的毕业设计项目案例&#xff0c;涵盖文本分类、生成式模型、语义理解、机器翻译、对话系统、情感分析等多个领域&#xff1a; 实现案例截图&#xff1a; 基于深度学习的文本分类系统基于BERT的情感分析系…