根据我的粗浅经验,如果您对Formik感兴趣,并且想深入学习与使用这个库,我建议您还是先对redux-form的使用逻辑与有关概念有所了解,而且理解和使用方面也变得容易得多的多。因为Formik中许多概念与形式与redux-form极其类似,但是各方面都简化了很多,因为它不再依赖于约束整个前面存储的Redux store的限制,由于整个前端使用一个store存储,所以,随着表单数量与形式变得越来越复杂,系统的属性可能会受到严重影响——这是Formik产生的主要原因,Formik干脆不使用Redux,而直接操作React组件,这就有可能使得编写表单元素虽然简单(HTML5)但比较冗长,于是Formik也引入了类似于redux-form的一些API与props等概念(但绝对有区别)。
另外请注意,为了与其他流行的React文章保持一致,有些单词没有必要翻译过来,例如store, values,props,shape,errors,等等。另外,touch和touched这个词在Formik中广泛使用,意思是表单中某个字段被点击过,此时用户可能没有输入什么数据,也有可能输入了新的数据,都称为touched。因此,后面的译文中一般翻译为「动过」,个别地方翻译成「润色」,请理解其使用情形就是。
<Formik>是一个帮助构建表单的组件,它也使用了类似于当前一些流行的库(如React Motion和 React Router)的render这种prop模式。请参考下面的代码:
import React from 'react';
import { Formik } from 'formik';
const BasicExample = () => (
<div>
<h2>My Form</h2>
<Formik
initialValues={{ name: 'jared' }}
onSubmit={(values, actions) => {
setTimeout(() => {
alert(JSON.stringify(values, null, 2));
actions.setSubmitting(false);
}, 1000);
}}
render={props => (
<form onSubmit={props.handleSubmit}>
<input
type="text"
onChange={props.handleChange}
onBlur={props.handleBlur}
value={props.values.name}
name="name"
/>
{props.errors.name && <div id="feedback">{props.errors.name}</div>}
<button type="submit">Submit</button>
</form>
)}
/>
</div>
);
<Formik />这个API共提供了三种渲染方法,它们是:
上面所有三种渲染方法都会传递相同的props。接下来,我们对props每一个分量作相应的解释。
当values与初始值不绝对相等时这个属性的值会返回true;否则返回false(Returns true if values are not deeply equal from initial values, false otherwise)。注意:dirty属性是只读的,不应该直接修改它。
其中包含Form校验错误信息。这些信息应当与表单的定义于initialValues中的值(values)保持一致。如果你在使用validationSchema(也推荐你使用),那么数据(原文使用的是“keys and shape”,关于shape一词在React文章中经常见到,这里不便直译)应当与你的模式定义准确匹配。 从内部实现代码来看,Formik会根据你提供的数据转换原始的Yup校验错误信息。如果你在使用validate属性,那么此函数会确定错误对象的具体信息。
这是onBlur对应的事件处理器函数。当你需要跟踪某个输入字段是否被“动过”(touched)时很有用。用法比如:<input onBlur={handleBlur} ... />
【注意】本属性仅适用于DOM开发;如果是React Native开发则需使用setFieldTouched代替。
这是一个典型的输入字段内容变化时要触发的事件处理器。当key为事件发出的输入字段的name属性时这一调用会更新values。如果name不存在,那么handleChange函数会进一步查找输入字段(input)的id属性。请注意: 这里的input意指所有HTML input标签。
【注意】本属性仅适用于DOM开发;如果是React Native开发则需使用setFieldValue代替。
这是表单复位处理器函数,调用它将把表单还原到初始值状态。用法比如:<button onClick={handleReset}>...</button>
这是表单提交处理器函数。 用法比如:<form onSubmit={props.handleSubmit}>...</form>。请结合本系列文章第一篇中「表单提交原理」部分加以理解。
这个属性值代表了表单提交的当前状态。如果表单在提交中将返回true;否则返回false。重要提醒:一旦你尝试提交表单,Formik就会把这个值设置为true。请结合本系列文章第一篇中「表单提交原理」部分加以理解。
在不发生错误的情况下这个属性值将为true;或者返回当表单处于pristine条件(例如没有dirty)时会返回isInitialValid的结果值。
如果Formik正在运行任何检验函数,则此属性返回true;否则,返回false。想更多地了解在表单提交过程中isValidating属性发生了什么变化,请结合阅读本系列文章第一篇中「表单提交原理」部分。
强行复位表单。这个调用会清除所有错误及字段「润色」信息,并且设置isSubmitting为false,设置isValidating为false,并且把mapPropsToValues返回值设置为当前的WrappedComponent的props或者是传递过去的参数。注意:当在componentWillReceiveProps内部调用resetForm时,这是很有用的。
强行设置errors信息。
强行设置给定字段的error信息。注意,这里的参数field应当匹配你希望更新的errors中的key。这个属性在编写定制的输入错误信息处理器函数时非常有用。
强行设置给定字段的touched状态值。注意,这里的参数field应当匹配你想更新的「动过」的key。这个属性在编写定制的blur处理器函数时非常有用。如果validateOnBlur的值设置为true(默认即为此值),那么调用这个方法会触发校验运行。你也可以通过传递第三个参数为false来显式地禁止或者跳过校验。
触发表单提交操作。
代表用户尝试提交表单的次数。当调用handleSubmit时此属性的值会加1;但是调用handleReset后该属性值会复位。请注意, submitCount是一个只读属性,不能直接修改。
强制设置一个字段的值。其中,参数field应当匹配你希望更新的values中的key。 该属性在编写定制的change事件处理函数时很有用。当validateOnChange为true (默认即是这个值)时,调用此属性对应的函数会触发校验的执行。当然,你还可以通过传递第三个参数为false来显式地禁止或者跳过校验。
强制设置一个顶级的状态值。这个调用用于控制你的表单的任意顶级状态。例如,你可以使用它来把API响应传递回在handleSubmit调用中的你的组件内部。
强制设置isSubmitting属性的值。
强制设置touched属性的值。
强制设置values对象的值。
这是一个顶级的状态对象,你可以使用它来描述使用其他方法无法表达/存储的表单状态。在捕获或者传递API响应给你的内部组件时这个属性很有用。
【注意】你仅能通过调用setStatus: (status?: any) => void来修改status。
此属性用于润色表单中对应的字段值。每一个键都相应于一个刚刚被「动过」(touched)或者访问过的字段。
这是你的表单中的values对象。其中存储了mapPropsToValues (如果指定的话)对应的结果数据,或者存储那些传递给你的被包装组件(wrapped component)的不是函数形式的props。
【说明】包装组件(wrapped component)一词在诸多React/Redux文章中多见,即是指使用类似于redux-form的reduxForm API封装后的新组件。
根据指定的方式强制你的validate属性对应的校验函数或者是调用validateSchema。注意,你可以选择性地传递数值进行校验,当然这将相应地修改Formik状态;否则,它会使用表单的当前values。
强制调用表单的validate属性对应的函数——如果指定了相应字段的话。Formik将使用当前字段值。
下面给出此属性的典型使用方法:
<Formik component={ContactForm} />;
const ContactForm = ({
handleSubmit,
handleChange,
handleBlur,
values,
errors,
}) => (
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={handleChange}
onBlur={handleBlur}
value={values.name}
name="name"
/>
{errors.name && <div>{errors.name}</div>}
<button type="submit">Submit</button>
</form>
};
【注意】<Formik component> 的优先级会高于<Formik render>;因此,你不要在同一个<Formik>中同时使用二者。
这个属性相当重要,请参考如下代码了解其用法:
<Formik render={props => <ContactForm {...props} />} />
<Formik
render={({ handleSubmit, handleChange, handleBlur, values, errors }) => (
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={handleChange}
onBlur={handleBlur}
value={values.name}
name="name"
/>
{errors.name &&
<div>
{errors.name}
</div>}
<button type="submit">Submit</button>
</form>
)}
/>
使用方法见下面的代码片断:
<Formik children={props => <ContactForm {...props} />} />
//或者使用下面的方式...
<Formik>
{({ handleSubmit, handleChange, handleBlur, values, errors }) => (
<form onSubmit={handleSubmit}>
<input
type="text"
onChange={handleChange}
onBlur={handleBlur}
value={values.name}
name="name"
/>
{errors.name &&
<div>
{errors.name}
</div>}
<button type="submit">Submit</button>
</form>
)}
</Formik>
默认值为false。此属性用于在initialValues变化时控制是否重置表单。
默认值为false。用于控制表单加载前的isValid属性的初始值。你也可以传递一个函数。此属性用于当你想在表单初始加载时启用/禁用一次提交/复位按钮操作时。
相应于表单初始字段值。Formik将使用这些值来生成例如props.values这样的方法组件。
即使你的表单默认情况下为空,你也必须使用初始值来初始化所有字段;否则,React会抛出异步,说你已经把一个输入字段从未控制(uncontrolled)状态改变成了可控制(controlled)状态。
【注意】 initialValues并不适用于高阶组件(higher-order component);在高阶组件情况下,你需要使用mapPropsToValues代之。
对应于你可选择使用的表单复位处理器函数。其中的参数是你的表单values,还有一个"FormikBag"值。
这是表单提交处理器函数。其中的参数是你的表单values,还有一个"FormikBag"值——其中提供了一个包含被注入的属性(props)和方法(例如所有以set开头——如set<Thing>的方法,还有方法resetForm)的子集的对象,以及传递给包装组件的任何props。
【注意】 errors, touched,status以及所有的事件处理器函数都没有包含在FormikBag参数中。
【注意】Formik作用特别推荐我们使用validationSchema和Yup实现表单校验。无论如何,表单校验应该使用一种相对独立的,比较直观的方式实现——这也是每一个所希望的。
另外,你可以使用同步或者异步函数来实现表单校验。请参考下面的代码:
(1)同步校验方式(返回一个errors对象)
// Synchronous validation
const validate = (values, props) => {
let errors = {};
if (!values.email) {
errors.email = 'Required';
} else if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(values.email)) {
errors.email = 'Invalid email address';
}
//...
return errors;
};
(2)异步校验方式(返回errors对象中的一个代表错误的Promise)
// Async Validation
const sleep = ms => new Promise(resolve => setTimeout(resolve, ms));
const validate = (values, props) => {
return sleep(2000).then(() => {
let errors = {};
if (['admin', 'null', 'god'].includes(values.username)) {
errors.username = 'Nice try';
}
// ...
if (Object.keys(errors).length) {
throw errors;
}
});
};
此属性的默认值为true。你可以在表单blur事件触发时使用这个属性——更具体一些说,无论是调用handleBlur,setFieldTouched还是setTouched都可以。
此属性的默认值为true。当表单触发change事件或者相关事件时你可以使用这个属性告诉Formik进行有关校验。 更具体一些说,无论是调用handleChange,setFieldValue还是setValues都可以。
这个属性非常重要,用于定义Yup模式( schema)或者是一个返回Yup模式的函数,用于校验任务。其中,Errors会通过key映射到内部组件的errors。这个属性的keys应当与values中的相匹配。
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。