提醒和建议
关于 )} /> );Formik渲染方法根据我的粗浅经验,如果您对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。因此,后面的译文中一般翻译为「动过」,个别地方翻译成「润色」,请理解其使用情形就是。
。请结合本系列文章第一篇中「表单提交原理」部分加以理解。
isSubmitting: boolean这个属性值代表了表单提交的当前状态。如果表单在提交中将返回true;否则返回false。重要提醒:一旦你尝试提交表单,Formik就会把这个值设置为true。请结合本系列文章第一篇中「表单提交原理」部分加以理解。
isValid: boolean在不发生错误的情况下这个属性值将为true;或者返回当表单处于pristine条件(例如没有dirty)时会返回isInitialValid的结果值。
isValidating: boolean如果Formik正在运行任何检验函数,则此属性返回true;否则,返回false。想更多地了解在表单提交过程中isValidating属性发生了什么变化,请结合阅读本系列文章第一篇中「表单提交原理」部分。
resetForm: (nextValues?: Values) => void强行复位表单。这个调用会清除所有错误及字段「润色」信息,并且设置isSubmitting为false,设置isValidating为false,并且把mapPropsToValues返回值设置为当前的WrappedComponent的props或者是传递过去的参数。注意:当在componentWillReceiveProps内部调用resetForm时,这是很有用的。
setErrors: (fields: { [field: string]: string }) => void强行设置errors信息。
setFieldError: (field: string, errorMsg: string) => void强行设置给定字段的error信息。注意,这里的参数field应当匹配你希望更新的errors中的key。这个属性在编写定制的输入错误信息处理器函数时非常有用。
setFieldTouched: (field: string, isTouched: boolean, shouldValidate?: boolean) => void强行设置给定字段的touched状态值。注意,这里的参数field应当匹配你想更新的「动过」的key。这个属性在编写定制的blur处理器函数时非常有用。如果validateOnBlur的值设置为true(默认即为此值),那么调用这个方法会触发校验运行。你也可以通过传递第三个参数为false来显式地禁止或者跳过校验。
submitForm: () => void触发表单提交操作。
submitCount: number代表用户尝试提交表单的次数。当调用handleSubmit时此属性的值会加1;但是调用handleReset后该属性值会复位。请注意, submitCount是一个只读属性,不能直接修改。
setFieldValue: (field: string, value: any, shouldValidate?: boolean) => void强制设置一个字段的值。其中,参数field应当匹配你希望更新的values中的key。 该属性在编写定制的change事件处理函数时很有用。当validateOnChange为true (默认即是这个值)时,调用此属性对应的函数会触发校验的执行。当然,你还可以通过传递第三个参数为false来显式地禁止或者跳过校验。
setStatus: (status?: any) => void强制设置一个顶级的状态值。这个调用用于控制你的表单的任意顶级状态。例如,你可以使用它来把API响应传递回在handleSubmit调用中的你的组件内部。
setSubmitting: (isSubmitting: boolean) => void强制设置isSubmitting属性的值。
setTouched: (fields: { [field: string]: boolean }) => void强制设置touched属性的值。
setValues: (fields: { [field: string]: any }) => void强制设置values对象的值。
status?: any这是一个顶级的状态对象,你可以使用它来描述使用其他方法无法表达/存储的表单状态。在捕获或者传递API响应给你的内部组件时这个属性很有用。
【注意】你仅能通过调用setStatus: (status?: any) => void来修改status。
此属性用于润色表单中对应的字段值。每一个键都相应于一个刚刚被「动过」(touched)或者访问过的字段。
values: { [field: string]: any }这是你的表单中的values对象。其中存储了mapPropsToValues (如果指定的话)对应的结果数据,或者存储那些传递给你的被包装组件(wrapped component)的不是函数形式的props。
【说明】包装组件(wrapped component)一词在诸多React/Redux文章中多见,即是指使用类似于redux-form的reduxForm API封装后的新组件。
根据指定的方式强制你的validate属性对应的校验函数或者是调用validateSchema。注意,你可以选择性地传递数值进行校验,当然这将相应地修改Formik状态;否则,它会使用表单的当前values。
validateField: (field: string) => void强制调用表单的validate属性对应的函数——如果指定了相应字段的话。Formik将使用当前字段值。
component下面给出此属性的典型使用方法:
};
【注意】 )}/>children: func
使用方法见下面的代码片断:
<Formik children={props => <ContactForm {...props} />} />
//或者使用下面的方式...
)}enableReinitialize?: boolean
默认值为false。此属性用于在initialValues变化时控制是否重置表单。
isInitialValid?: boolean默认值为false。用于控制表单加载前的isValid属性的初始值。你也可以传递一个函数。此属性用于当你想在表单初始加载时启用/禁用一次提交/复位按钮操作时。
initialValues?: Values相应于表单初始字段值。Formik将使用这些值来生成例如props.values这样的方法组件。
即使你的表单默认情况下为空,你也必须使用初始值来初始化所有字段;否则,React会抛出异步,说你已经把一个输入字段从未控制(uncontrolled)状态改变成了可控制(controlled)状态。
【注意】 initialValues并不适用于高阶组件(higher-order component);在高阶组件情况下,你需要使用mapPropsToValues代之。
对应于你可选择使用的表单复位处理器函数。其中的参数是你的表单values,还有一个"FormikBag"值。
onSubmit: (values: Values, formikBag: FormikBag) => void这是表单提交处理器函数。其中的参数是你的表单values,还有一个"FormikBag"值——其中提供了一个包含被注入的属性(props)和方法(例如所有以set开头——如set
【注意】 errors, touched,status以及所有的事件处理器函数都没有包含在FormikBag参数中。
validate?: (values: Values) => FormikErrors【注意】Formik作用特别推荐我们使用validationSchema和Yup实现表单校验。无论如何,表单校验应该使用一种相对独立的,比较直观的方式实现——这也是每一个所希望的。
另外,你可以使用同步或者异步函数来实现表单校验。请参考下面的代码:
(1)同步校验方式(返回一个errors对象)
// Synchronous validationconst 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 Validationconst 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; } });};validateOnBlur?: boolean此属性的默认值为true。你可以在表单blur事件触发时使用这个属性——更具体一些说,无论是调用handleBlur,setFieldTouched还是setTouched都可以。
validateOnChange?: boolean此属性的默认值为true。当表单触发change事件或者相关事件时你可以使用这个属性告诉Formik进行有关校验。 更具体一些说,无论是调用handleChange,setFieldValue还是setValues都可以。
validationSchema?: Schema | (() => Schema)这个属性非常重要,用于定义Yup模式( schema)或者是一个返回Yup模式的函数,用于校验任务。其中,Errors会通过key映射到内部组件的errors。这个属性的keys应当与values中的相匹配。



