Overview 概述
Formik 是一个小型表单库帮你处理最烦人的 3 部分:
- 表单值存取 - Getting values in and out of form state
- 表单验证 - Validation and error messages
- 表单提交 - Handling form submission
通过将上述 3 部分有组织地管理在同一个地方,Formik 使得测试、重构和推理变得简单。
我们不仅可以通过标准化表单组件,还可以通过标准化 表单数据流(数据在表单中的流动方式) 以获取便捷和推理。
The Basics 基础
在本教程中,我们将使用 React 和 Formik 构建一个复杂的 newsletter(电子期刊)注册表单。
假设我们想为一个博客添加一个 newsletter(电子期刊)注册表单。首先,我们的表单只有一个名为 email
的字段。
我们将表单的 initialValues(表单初始值)和 onSubmit(表单提交函数)传递给 useFormik() 钩子函数,函数返回给我们一个 form state(表单状态)和 helper methods(表单工具函数)的 formik 变量。
现在,我们唯一关心的表单工具函数是:
- handleSubmit, 表单提交处理函数
- handleChange, 表单组件值变更处理函数
values
, 表单当前值
我们现在拥有由 Formik 提供标准化封装的表单。不用自己管理表单的值,也不用为每个表单组件编写自定义事件处理函数,只需使用 useFormik() 即可。
接下来我们再添加 2 个 input 表单组件,分别存储用户的 firstName
(名字)和 lastName
(姓氏)。
如果你仔细看我们的代码,你会注意到一些模式和共性。
- 所有表单组件共用 handleChange 表单组件值变更处理函数;
- 表单组件的 id 和 name 属性与 initialValues 表单初始值中定义的属性名称保持一致。
如果需要你手动实现 handleChange 函数,不难想象它内部实现是这样的:
Validation 表单验证
Formik 不仅跟踪表单的值,还跟踪表单的验证和错误消息。要添加表单验证,我们需要编写 validate 表单验证函数传递给 useFormik() 钩子函数。如果验证失败,表单验证函数会生成和 values / initialValues 结构匹配的 errors
错误对象返回。
默认情况下,Formik 会在每次键盘事件、组件 blur 事件以及表单提交前进行验证。表单提交 onSubmit 函数只有在没有错误的情况下才会执行( validate 函数返回 {})。
由于验证函数在对整个表单值进行验证,因此 errors 对象在任意时刻都包含所有验证错误。这很不友好,因为我们会显示用户还没有访问过的字段的错误消息。大多数情况下,我们希望只有在用户输入该字段后才显示该字段的错误消息。
Formik 跟踪哪些字段被访问过并存储在 touched
对象中。对象的属性值是 true / false 布尔值,代表该字段是否被访问过。
使用 Yup 进行表单验证
由于 Formik 的作者非常喜欢 Yup,所以 Formik 为 Yup 专门提供了一个名为 validationSchema 的特殊配置属性。
validationSchema 会自动将 Yup 的验证结果转换为一个漂亮的 errors 错误对象,其键匹配 values / initialValues 对象。
Formik 的核心设计原则之一就是帮助你保持组织性。在这一点上 Yup 确实有很大的帮助,模式极具表现力、直觉性,而且可重用。
Reducing Boilerplate 减少样板代码
上述表单组件赋值 formik 属性有很大共同点,useFormik() 返回的 getFieldProps() 函数可以帮助你减少样板代码。
getFieldProps() 函数会返回一个包含 name
、value
、onBlur
、onChange
属性的 fieldProps 对象便于直接解构赋值给表单组件。
上面的代码仍然需要我们手动传递每个表单组件予 getFieldProps()。为了节省更多的时间,Formik 提供 React 上下文驱动的 API / 组件,使代码更少冗长。
Wrapping Up 结束
最后,我们可以通过 useField() 钩子函数来自定义我们自己的 组件。这些自定义 Field 组件可以在应用中被复用。