概述

让我们面对现实,表单在 React 中非常冗长。更糟糕的是,大多数表单助手都做了太多“魔法”,并且通常与它们相关的性能成本很高。Formik 是一个小型库,可以帮助您解决三个最令人头疼的部分

  1. 将值输入和输出表单状态
  2. 验证和错误消息
  3. 处理表单提交

通过将以上所有内容集中在一个地方,Formik 将保持事物的井然有序,从而使测试、重构和推理解析您的表单变得轻而易举。

动机

我 (@jaredpalmer) 在与 @eonwhite 构建大型内部管理仪表板时编写了 Formik。大约有 30 个独特的表单,很快我们就意识到,我们可以通过标准化我们的输入组件以及数据流经表单的方式来获益。

为什么不使用 Redux-Form?

到现在为止,您可能在想,“为什么不直接使用 Redux-Form?” 这是一个好问题。

  1. 根据我们的先知 Dan Abramov,表单状态本质上是短暂的和局部的,因此在 Redux(或任何类型的 Flux 库)中跟踪它是没有必要的
  2. Redux-Form 会在每次按键时多次调用您的整个顶级 Redux reducer。对于小型应用程序来说,这很好,但是随着 Redux 应用程序的增长,如果您使用 Redux-Form,输入延迟将持续增加。
  3. Redux-Form 压缩后大小为 22.5 kB(Formik 为 12.7 kB)

我使用 Formik 的目标是创建一个可扩展、高性能的表单助手,它具有最小的 API,可以完成真正令人头疼的事情,并将其他事情留给您。


我在 React Alicante 的演讲更深入地探讨了 Formik 的动机和理念,介绍了该库(通过观看我构建它的迷你版本),并演示了如何使用真实库构建一个非平凡的表单(带有数组、自定义输入等)。

影响

Formik 最初是基于 这个小的高阶组件(由 Brent Jackson 编写),一些来自 Redux-Form 的命名约定,以及(最近)由 React-MotionReact-Router 4 推广的 render props 方法。无论您是否使用过上述任何一种方法,Formik 都只需几分钟即可上手。

安装

您可以使用 NPMYarn 或通过 unpkg.com 使用传统的 <script> 安装 Formik。

NPM

npm install formik --save

yarn add formik

Formik 与 React v15+ 兼容,并适用于 ReactDOM 和 React Native。

您也可以在购买前尝试一下这个 **Formik 在 CodeSandbox.io 上的演示**

浏览器游乐场

您可以在 Web 浏览器中使用这些在线游乐场来体验 Formik。

要点

Formik 跟踪表单的状态,然后通过 props 将其以及一些可重用方法和事件处理程序(handleChangehandleBlurhandleSubmit)公开给您的表单。handleChangehandleBlur 的工作方式与预期完全一样——它们使用 nameid 属性来确定要更新哪个字段。

import React from 'react';
import { Formik } from 'formik';
const Basic = () => (
<div>
<h1>Anywhere in your app!</h1>
<Formik
initialValues={{ email: '', password: '' }}
validate={values => {
const errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
) {
errors.email = 'Invalid email address';
}
return errors;
}}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
{({
values,
errors,
touched,
handleChange,
handleBlur,
handleSubmit,
isSubmitting,
/* and other goodies */
}) => (
<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}>
Submit
</button>
</form>
)}
</Formik>
</div>
);
export default Basic;

减少样板代码

上面的代码非常明确地说明了 Formik 在做什么。onChange -> handleChangeonBlur -> handleBlur,依此类推。但是,为了节省您的时间,Formik 附带了一些额外的组件,使生活更轻松、更简洁:<Form /><Field /><ErrorMessage />。它们使用 React 上下文来挂接到父 <Formik /> 状态/方法上。

// Render Prop
import React from 'react';
import { Formik, Form, Field, ErrorMessage } from 'formik';
const Basic = () => (
<div>
<h1>Any place in your app!</h1>
<Formik
initialValues={{ email: '', password: '' }}
validate={values => {
const errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (
!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
) {
errors.email = 'Invalid email address';
}
return errors;
}}
onSubmit={(values, { setSubmitting }) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
setSubmitting(false);
}, 400);
}}
>
{({ isSubmitting }) => (
<Form>
<Field type="email" name="email" />
<ErrorMessage name="email" component="div" />
<Field type="password" name="password" />
<ErrorMessage name="password" component="div" />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
</div>
);
export default Basic;

阅读以下内容以获取更多信息…

补充包

如上所示,验证留给您自己处理。您可以自由编写自己的验证器或使用第三方库。就我个人而言,我使用 Yup 进行对象模式验证。它具有与 Joi / React PropTypes 非常相似的 API,但它足够小,可以用于浏览器,并且速度足够快,可以用于运行时使用。因为我非常喜欢 Yup,所以 Formik 有一个特殊的配置选项/属性用于 Yup,称为 validationSchema,它会自动将 Yup 的验证错误转换为一个漂亮的对象,其键与 valuestouched 匹配。无论如何,您可以从 npm 安装 Yup…

npm install yup --save

yarn add yup
此页面是否有帮助?

订阅我们的时事通讯

最新的 Formik 新闻、文章和资源,发送到您的收件箱。

版权所有 © 2020 Formium, Inc. 保留所有权利。