id: overview

title: Overview

让我们面对现实,React的(form)表单真的很冗长。更糟糕的是,大多数表单的帮助库都做了太多魔术(wayyyy),并且往往会产生与之相关的显着性能成本。Formik 是一个小型库,可以帮助您解决 3 个最烦人的部分:

    1. 获取表单状态的值和表单状态
    1. 验证和错误消息
    1. 处理表单提交

formik 通过把上面的所有内容放在一个地方,使事情变得井然有序——让您的表单的测试、重构和理解变得轻而易举。

动机

我(我)jaredpalmer@)在构建@eonwhite大型内部管理仪表盘搞出了 Formik。 由于大约有 30 种独特的表单,很快我们就可以通过标准化输入组件以及数据,以此贯通表单联系的方式,很有帮助。

为什么不用 Redux-Form?

现在,你可能在想,“你为什么不直接用Redux-Form?”,这问得好

  1. 据我们的’先知’ Dan Abramov 所说,form 状态本质上是短暂的且局部的 因此,在 redux(或任何类型的 flux 库)中跟踪它是不必要的。
  2. 每次触发一个键(ON EVERY SINGLE KEYSTROKE),Redux-Form 都会多次调用整个顶级 Redux Reducer。对于小型应用程序来说,这很好,但是随着 Redux 应用程序的增长,如果使用 Redux-Form,输入延迟将继续增加。
  3. Redux-Form 缩 gzip 格式为 22.5 kb (Formik 为 12.7 kb)

formik 的目标是创建一个可扩展的、性能良好的表单助手,它使用一个最小的 API 来完成真正厌烦的事情,剩下的就交给你了。


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

影响

Formik 由Brent Jackson这个小的高阶组件开始诞生的,,具有 Redux-Form 的一些命名约定,以及(最近)React-MotionReact-Router 4的渲染 props 方法。 无论你是否使用过上述任何一种,Formik 只需要几分钟就可以入门。

安装

您可以用NPMyarn安装,或者一个好的<script>unpkg.com.

NPM

  1. npm install formik --save
  2. # or
  3. yarn add formik

formik 与 react v15+兼容,与 reactdom 和 react native 兼容。

你可以 在 codesandbox.io 上演示 formik。,不甜不收钱。

CDN

如果您不使用模块绑定器或包管理器,我们也有一个全局(“UMD”)构建托管在unpkg.comCDN。只需添加以下内容<script>标签到 HTML 文件的底部:

  1. <script src="https://unpkg.com/formik/dist/formik.umd.production.js"></script>

添加后,您将可以访问window.Formik.<Insert_Component_Name_Here>变量。

此安装方式/的使用,是要求React cdn 脚本包也会出现在页面上。

在浏览器中的游乐场

你可以在网络浏览器中,使用这些在线游戏场来玩 formik。

要旨

formik 跟踪表单的状态,然后将其公开,再加上一些可重用的方法和事件处理程序(handleChangehandleBlurhandleSubmit),本质上是通过props. handleChangehandleBlur来达到预期工作 —— 他们使用nameid属性来确定要更新的字段。

  1. import React from 'react';
  2. import {Formik} from 'formik';
  3. const Basic = () => (
  4. <div>
  5. <h1>Anywhere in your app!</h1>
  6. <Formik
  7. initialValues={{email: '', password: ''}}
  8. validate={values => {
  9. let errors = {};
  10. if (!values.email) {
  11. errors.email = 'Required';
  12. } else if (
  13. !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
  14. ) {
  15. errors.email = 'Invalid email address';
  16. }
  17. return errors;
  18. }}
  19. onSubmit={(values, {setSubmitting}) => {
  20. setTimeout(() => {
  21. alert(JSON.stringify(values, null, 2));
  22. setSubmitting(false);
  23. }, 400);
  24. }}
  25. >
  26. {({
  27. values,
  28. errors,
  29. touched,
  30. handleChange,
  31. handleBlur,
  32. handleSubmit,
  33. isSubmitting
  34. /* and other goodies */
  35. }) => (
  36. <form onSubmit={handleSubmit}>
  37. <input
  38. type="email"
  39. name="email"
  40. onChange={handleChange}
  41. onBlur={handleBlur}
  42. value={values.email}
  43. />
  44. {errors.email && touched.email && errors.email}
  45. <input
  46. type="password"
  47. name="password"
  48. onChange={handleChange}
  49. onBlur={handleBlur}
  50. value={values.password}
  51. />
  52. {errors.password && touched.password && errors.password}
  53. <button type="submit" disabled={isSubmitting}>
  54. Submit
  55. </button>
  56. </form>
  57. )}
  58. </Formik>
  59. </div>
  60. );
  61. export default Basic;

还原样板

上面的代码非常明确地说明了 formik 正在做什么。onChange->handleChangeonBlur->handleBlur等等。不过,为了节省时间,Formik 还提供了一些额外的组件,以使生活更轻松、更不冗长:<Form /><Field /><ErrorMessage />. 它们使用 react 上下文,来钩住父级<Formik />的状态/方法。

  1. // Render Prop
  2. import React from 'react';
  3. import {Formik, Form, Field, ErrorMessage} from 'formik';
  4. const Basic = () => (
  5. <div>
  6. <h1>Any place in your app!</h1>
  7. <Formik
  8. initialValues={{email: '', password: ''}}
  9. validate={values => {
  10. let errors = {};
  11. if (!values.email) {
  12. errors.email = 'Required';
  13. } else if (
  14. !/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}$/i.test(values.email)
  15. ) {
  16. errors.email = 'Invalid email address';
  17. }
  18. return errors;
  19. }}
  20. onSubmit={(values, {setSubmitting}) => {
  21. setTimeout(() => {
  22. alert(JSON.stringify(values, null, 2));
  23. setSubmitting(false);
  24. }, 400);
  25. }}
  26. >
  27. {({isSubmitting}) => (
  28. <Form>
  29. <Field type="email" name="email" />
  30. <ErrorMessage name="email" component="div" />
  31. <Field type="password" name="password" />
  32. <ErrorMessage name="password" component="div" />
  33. <button type="submit" disabled={isSubmitting}>
  34. Submit
  35. </button>
  36. </Form>
  37. )}
  38. </Formik>
  39. </div>
  40. );
  41. export default Basic;

补充包

正如您在上面看到的,验证由您自己决定。您可以编写自己的验证器或使用第三方库。我个人用Yup搞定对象结构验证。它有一个与Joi / React PropTypes非常相似的 API,但是对于浏览器来说足够小,对于浏览引擎的使用来说足够快。因为 I :heart: Yup sooo much,Formik 为 yup 提供了一个特殊的配置 options /props,叫做validationSchema,它会自动将 yup 的验证错误转换成一个, key 匹配valuestouched的漂亮对象。 总的来说,你可以从 NPM 安装 Yup…

  1. npm install yup --save