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

news2024/12/27 10:31:51
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.coloradmin.cn/o/2171360.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

一文彻底掌握inout双向端口

inout端口信号在FPGA中应用还是很广泛的&#xff0c;特别是一些总线通信、数据交互的场景&#xff0c;比如i2c、spi等等。 一、inout的基本概念 Inout 端口的实现基础是三态门。 三态门具有三种输出状态&#xff0c;即高电平、低电平以及高阻态&#xff08;Z&#xff09;。 …

win11下 keil报错Cannot load driver ‘D:\Keil_v5\ARM\Segger\JL2CM3.dll‘

现象 更新系统后&#xff08;win10->win11&#xff09;,发现Keil编译或者调试居然报错了&#xff1a; 但是在该路径下&#xff0c;还是能找到JL2CM3.dll这个文件的 解决方法 进入系统环境变量设置 在Path添加环境变量JL2CM3.dll所在路径&#xff0c;我这里就是‘D:\Keil_v…

中国新媒体联盟与中运律师事务所 建立战略合作伙伴关系

2024年9月27日&#xff0c;中国新媒体联盟与中运律师事务所举行战略合作协议签字仪式。中国新媒体联盟主任兼中国社会新闻网主编、中法新闻法制网运营中心主任左新发&#xff0c;中运律师事务所高级顾问刘学伟代表双方单位签字。 中国新媒体联盟是由央视微电影中文频道联合多家…

jupyter使用pytorch

1、激活环境 以下所有命令都在Anaconda Prompt中操作。 conda activate 环境名称我的环境名称是myenv 如果不知道自己的pytorch配在哪个环境&#xff0c;就用下面方法挨个试。 2、安装jupyter 1、安装 pip install jupyter2、如果已经安装&#xff0c;检查jupyter是否已…

第五部分:5---三张信号表,信号表的系统调用

目录 信号的递达、未决、阻塞&#xff1a; 进程维护的三张信号表&#xff1a; 普通信号与实时信号的记录&#xff1a; 信号结构的系统调用&#xff1a; bolck表的系统调用&#xff1a; 实例&#xff1a;设置屏蔽信号集中的所有信号都频闭 pending表读取&#xff1a; 信号…

第一本RAG书籍《大模型RAG实战》出版!

随着ChatGPT的爆火&#xff0c;推动了新一轮的AI技术进步。但大模型自身存在幻觉、知识更新难等问题&#xff0c;阻碍了其直接进行落地应用。RAG&#xff08;Retrieval-Augmented Generation&#xff09;技术将LLM与文本信息检索相结合&#xff0c;解决了在一些场景下模型知识不…

数字人直播违规原因究竟是什么?哪些技术可以解决?

随着人工智能时代的来临&#xff0c;以数字人直播为代表的技术应用逐渐被各大中小型企业引进&#xff0c;并成为了它们在直播板块降本增效的利器。不过&#xff0c;从目前的应用情况来看&#xff0c;不少企业都在使用数字人无人直播的过程中遭遇了违规封号的问题。在此背景下&a…

每天分享一个FPGA开源代码(7)- 6种乘法运算实现

​ FPGA开发中经常会遇到各种乘法运算。 这里分享下各种实现&#xff1a; Array Multiplier&#xff08;阵列乘法器&#xff09;、Complex Multiplier&#xff08;复数乘法器&#xff09;、Fraction Multiplier&#xff08;分数乘法器&#xff09;、High Radix Multiplier&a…

基于大数据技术的音乐数据分析及可视化系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、Vue项目源码、SSM项目源码 精品专栏&#xff1a;Java精选实战项目…

rk3588s android12 自启动 C程序

首先是 拷贝 TEST程序 到android跟文件系统看看能否成功。 首先将需要 在android 系统中 启动的 TEST 程序,拷贝到虚拟机。 这个程序 然后需要拷贝到 android 的文件系统中。 我是这样做的。 改的是这个文件。 然后, 编译+烧写测试。 发现, 在android 系…

detectron2是怎么建立模型的?以SparseInst代码为例

看SparseInst论文发现论文里有些地方没讲清楚&#xff1b;遂找SparseInst源码来看模型结构 我选择从推理代码来找模型结构&#xff1a; 经探索&#xff0c;在SparseInst代码里&#xff0c;推理需要执行代码 python demo.py --config-file configs/sparse_inst_r50_base.yaml …

Verilog基础:时序调度中的竞争(四)(描述时序逻辑时使用非阻塞赋值)

相关阅读 Verilog基础https://blog.csdn.net/weixin_45791458/category_12263729.html?spm1001.2014.3001.5482 作为一个硬件描述语言&#xff0c;Verilog HDL常常需要使用语句描述并行执行的电路&#xff0c;但其实在仿真器的底层&#xff0c;这些并行执行的语句是有先后顺序…

Python精选200Tips:176-180

针对图像的经典卷积网络结构进化史及可视化 P176--LeNet-5【1988】模型结构说明模型结构代码模型结构可视化 P177--AlexNet【2012】模型结构及创新性说明模型结构代码模型结构可视化 P178--VGGNet【2014】VGG19模型结构及创新性说明VGG19模型结构代码VGG19模型结构可视化 P179-…

Datawhale Leecode基础算法篇 task04:贪心算法

官方学习文档&#xff1a;datawhalechina 往期task01&#xff1a;枚举算法链接&#xff1a;Datawhale Leecode基础算法篇 task01&#xff1a;枚举算法 往期task02&#xff1a;递归算法and分治算法&#xff1a;Datawhale Leecode基础算法篇 task02&#xff1a;递归算法and分治…

项目实战:k8s部署考试系统

一、新建nfs服务器&#xff08;192.168.1.44&#xff09; 1.基础配置&#xff08;IP地址防火墙等&#xff09; 2.配置时间同步 [rootlocalhost ~]# yum -y install ntpdate.x86_64 [rootlocalhost ~]# ntpdate time2.aliyun.com 27 Sep 10:28:08 ntpdate[1634]: adjust tim…

风景视频素材高清无水印怎么找?推荐几个风景视频素材下载网站

那些绝美的大自然风景视频素材都在哪里找的&#xff1f;今天就跟大家聊聊那些可以下载高清无水印的大自然风景视频素材的网站&#xff0c;如果你也在苦苦寻找&#xff0c;快来看看吧&#xff5e; 1. 稻虎网 稻虎网作为国内遥遥领先的视频素材网站&#xff0c;提供了大量高清无…

2024最新Linux Socket编程

我们深谙信息交流的价值&#xff0c;那网络中进程之间如何通信&#xff0c;如我们每天打开浏览器浏览网页时&#xff0c;浏览器的进程怎么与web服务器通信的&#xff1f;当你用QQ聊天时&#xff0c;QQ进程怎么与服务器或你好友所在的QQ进程通信&#xff1f;这些都得靠socket&am…

Meta广告资料库使用教程:Facebook、Instagram海外社媒营销统统拿下!

社交媒体现今已成为大部分商家宣传推广方案中的重要工具&#xff0c;尤其是Meta旗下的两个主流社媒平台Facebook和Instagram&#xff0c;活跃用户数量以数十亿计&#xff0c;分布地区也非常广。要运用好自带影响力的社媒平台的传播力量和庞大数据&#xff0c;优化自身的宣传推广…

【Kubernetes】常见面试题汇总(四十二)

目录 96. Kubernetes 体系结构有哪些不同的组成部分&#xff1f; 97.您能否简要介绍一下 Kubernetes 中主节点的工作&#xff1f; 特别说明&#xff1a; 题目 1-68 属于【Kubernetes】的常规概念题&#xff0c;即 “ 汇总&#xff08;一&#xff09;~&#xff08;二十二…

亚马逊 Bedrock 平台也能使用Llama 3.2 模型了

亚马逊 Bedrock 平台推出 Llama 3.2 模型&#xff1a;多模态视觉和轻量级模型 概述 由 Meta 提供的最新 Llama 3.2 模型现已在 Amazon Bedrock 平台上推出。这一新模型系列标志着 Meta 在大型语言模型&#xff08;LLM&#xff09;领域的最新进展&#xff0c;它在多种应用场景…