<Formik> 是一个帮助你构建表单的组件。它使用了由 React Motion 和 React Router 等库推广的 render props 模式。
import React from 'react';import { Formik } from 'formik';const BasicExample = () => (<div><h1>My Form</h1><FormikinitialValues={{ name: 'jared' }}onSubmit={(values, actions) => {setTimeout(() => {alert(JSON.stringify(values, null, 2));actions.setSubmitting(false);}, 1000);}}>{props => (<form onSubmit={props.handleSubmit}><inputtype="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>)}</Formik></div>);
有两种方法可以使用 <Formik /> 渲染内容
<Formik 组件><Formik 子元素><Formik render>每个渲染方法都将传递相同的属性
dirty: boolean如果值与初始值不完全相等,则返回 true,否则返回 false。dirty 是一个只读计算属性,不应直接修改。
errors: { [field: string]: string }表单验证错误。应与你在 initialValues 中定义的表单 values 的形状匹配。如果你正在使用 validationSchema(你应该使用),键和形状将完全匹配你的模式。在内部,Formik 会代表你转换原始的 Yup 验证错误。如果你正在使用 validate,则该函数将确定 errors 对象的形状。
handleBlur: (e: any) => voidonBlur 事件处理程序。当你需要跟踪输入是否已被 touched 时很有用。这应该传递给 <input onBlur={handleBlur} ... />
handleChange: (e: React.ChangeEvent<any>) => void通用输入更改事件处理程序。这将更新 values[key],其中 key 是发出事件的输入的 name 属性。如果 name 属性不存在,handleChange 将查找输入的 id 属性。注意:“输入”在这里指的是所有 HTML 输入。
handleReset: () => void重置处理程序。将表单重置到其初始状态。这应该传递给 <button onClick={handleReset}>...</button>
handleSubmit: (e: React.FormEvent<HTMLFormElement>) => void提交处理程序。这应该传递给 <form onSubmit={props.handleSubmit}>...</form>。要了解有关提交过程的更多信息,请参阅 表单提交。
isSubmitting: boolean表单的提交状态。如果提交正在进行,则返回 true,否则返回 false。重要:Formik 会在尝试提交后立即将此设置为 true。要了解有关提交过程的更多信息,请参阅 表单提交。
isValid: boolean如果没有 errors(即 errors 对象为空),则返回 true,否则返回 false。
注意:
isInitialValid在 2.x 中已弃用。但是,为了向后兼容,如果指定了isInitialValid属性,则如果errors不存在,或者表单处于“原始”状态(即不为dirty)时isInitialValid的结果,isValid将返回true。
isValidating: boolean如果 Formik 在提交期间或通过调用[validateForm]直接运行验证,则返回 true,否则返回 false。要了解有关提交过程中 isValidating 发生的情况的更多信息,请参阅 表单提交。
resetForm: (nextState?: Partial<FormikState<Values>>) => void以命令式方式重置表单。唯一(可选)的参数 nextState 是一个对象,其中任何这些 FormikState 字段都是可选的
interface FormikState<Values> {/** Form values */values: Values;/** map of field names to specific error for that field */errors: FormikErrors<Values>;/** map of field names to **whether** the field has been touched */touched: FormikTouched<Values>;/** whether the form is currently submitting */isSubmitting: boolean;/** whether the form is currently validating (prior to submission) */isValidating: boolean;/** Top level status state, in case you need it */status?: any;/** Number of times user tried to submit the form */submitCount: number;}
如果指定了 nextState,Formik 将设置 nextState.values 作为新的“初始状态”,并使用 nextState 的相关值来更新表单的 initialValues 以及 initialTouched、initialStatus、initialErrors。这对于在更改后更改表单的初始状态(即“基础”)很有用。
// typescript usagefunction MyForm(props: MyFormProps) {// using TSX Generics here to set <Values> to <Blog>return (<Formik<Blog>initialValues={props.initVals}onSubmit={(values, actions) => {props.onSubmit(values).then(() => {actions.setSubmitting(false);actions.resetForm({values: {// the type of `values` inferred to be Blogtitle: '',image: '',body: '',},// you can also set the other form states here});});}}>// etc</Formik>);}
如果省略了 nextState,则 Formik 将状态重置为原始初始状态。后者对于在 componentDidUpdate 或 useEffect 中调用 resetForm 很有用。
actions.resetForm();
setErrors: (fields: { [field: string]: string }) => void以命令式方式设置 errors。
setFieldError: (field: string, errorMsg: string) => void以命令式方式设置字段的错误消息。field 应与你希望更新的 errors 的键匹配。对于创建自定义输入错误处理程序很有用。
setFieldTouched: (field: string, isTouched?: boolean, shouldValidate?: boolean) => Promise<void | FormikErrors>以命令式方式设置字段的 touched 状态。field 应与你希望更新的 touched 的键匹配。对于创建自定义输入 blur 处理程序很有用。如果 validateOnBlur 设置为 true(默认情况下为 true),则调用此方法将触发验证运行。如果未指定,则 isTouched 默认为 true。你还可以通过将第三个参数传递为 false 来显式阻止/跳过验证。
如果 validateOnBlur 设置为 true 并且存在错误,则将在返回的 Promise 中解析它们。
submitForm: () => Promise触发表单提交。如果表单无效,则 promise 将被拒绝。
submitCount: number用户尝试提交表单的次数。当调用 handleSubmit 时增加,在调用 handleReset 后重置。submitCount 是只读计算属性,不应直接修改。
setFieldValue: (field: string, value: React.SetStateAction<any>, shouldValidate?: boolean) => Promise<void | FormikErrors>以命令式方式设置字段的值。field 应与你希望更新的 values 的键匹配。对于创建自定义输入更改处理程序很有用。如果 validateOnChange 设置为 true(默认情况下为 true),则调用此方法将触发验证运行。你还可以通过将第三个参数传递为 false 来显式阻止/跳过验证。
如果 validateOnChange 设置为 true 并且存在错误,则将在返回的 Promise 中解析它们。
setStatus: (status?: any) => void以命令式方式将顶级 status 设置为你想要的任何内容。对于控制与你的表单相关的任意顶级状态很有用。例如,你可以在 handleSubmit 中使用它将 API 响应传递回你的组件。
setSubmitting: (isSubmitting: boolean) => void以命令式方式设置 isSubmitting。你将在你的 onSubmit 处理程序中使用 setSubmitting(false) 来完成循环。要了解有关提交过程的更多信息,请参阅 表单提交。
setTouched: (fields: { [field: string]: boolean }, shouldValidate?: boolean) => Promise<void | FormikErrors>以命令式方式设置 touched。如果 validateOnBlur 设置为 true(默认情况下为 true),则调用此方法将触发验证运行。你还可以通过将第二个参数传递为 false 来显式阻止/跳过验证。
如果 validateOnBlur 设置为 true 并且存在错误,则将在返回的 Promise 中解析它们。
setValues: (fields: React.SetStateAction<{ [field: string]: any }>, shouldValidate?: boolean) => Promise<void | FormikErrors<Values>>以命令式方式设置 values。如果 validateOnChange 设置为 true(默认情况下为 true),则调用此方法将触发验证运行。你还可以通过将第二个参数传递为 false 来显式阻止/跳过验证。
如果 validateOnChange 设置为 true 并且存在错误,则将在返回的 Promise 中解析它们。
status?: any一个顶级状态对象,你可以使用它来表示无法通过其他方法表达/存储的表单状态。这对于捕获并将 API 响应传递到你的内部组件很有用。
status 只能通过调用 setStatus 来修改。
touched: { [field: string]: boolean }已触碰的字段。每个键对应一个已被触碰/访问的字段。
values: { [field: string]: any }表单的值。其结构将与mapPropsToValues(如果指定)的结果相同,或者与传递给包装组件的所有非函数 props 相同。
validateForm: (values?: any) => Promise<FormikErrors<Values>>根据指定的 validate 或 validateSchema 规范,以命令式方式调用它们。您可以选择传递要验证的值,并相应地修改 Formik 状态,否则将使用表单当前的 values。
validateField: (field: string) => void如果为给定字段指定了 field 的 validate 函数,则以命令式方式调用该函数;否则,使用Yup 的 schema.validateAt 和提供的顶级 validationSchema prop 进行模式验证。Formik 将使用当前的字段值。
component?: React.ComponentType<FormikProps<Values>><Formik component={ContactForm} />;const ContactForm = ({handleSubmit,handleChange,handleBlur,values,errors,}) => (<form onSubmit={handleSubmit}><inputtype="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> 中同时使用两者。
render: (props: FormikProps<Values>) => ReactNode在 2.x 版本中已弃用。
<Formik render={props => <ContactForm {...props} />} /><Formikrender={({ handleSubmit, handleChange, handleBlur, values, errors }) => (<form onSubmit={handleSubmit}><inputtype="text"onChange={handleChange}onBlur={handleBlur}value={values.name}name="name"/>{errors.name &&<div>{errors.name}</div>}<button type="submit">Submit</button></form>)}/>
children?: React.ReactNode | (props: FormikProps<Values>) => ReactNode<Formik children={props => <ContactForm {...props} />} />// or...<Formik>{({ handleSubmit, handleChange, handleBlur, values, errors }) => (<form onSubmit={handleSubmit}><inputtype="text"onChange={handleChange}onBlur={handleBlur}value={values.name}name="name"/>{errors.name &&<div>{errors.name}</div>}<button type="submit">Submit</button></form>)}</Formik>
enableReinitialize?: boolean默认值为 false。控制 initialValues 发生更改时(使用深度相等性),Formik 是否应重置表单。
isInitialValid?: boolean在 2.x 版本中已弃用,请改用 initialErrors。
控制挂载前 isValid prop 的初始值。您还可以传递一个函数。在您希望在初始挂载时启用/禁用提交和重置按钮的情况下很有用。
initialErrors?: FormikErrors<Values>表单的初始字段错误,Formik 将使这些值可供渲染方法组件作为 errors 使用。
注意:高阶组件 withFormik 无法访问 initialErrors,请改用 mapPropsToErrors。
initialStatus?: any表单初始 status 的任意值。如果表单重置,将恢复此值。
注意:高阶组件 withFormik 无法访问 initialStatus,请改用 mapPropsToStatus。
initialTouched?: FormikTouched<Values>表单的初始已访问字段,Formik 将使这些值可供渲染方法组件作为 touched 使用。
注意:高阶组件 withFormik 无法访问 initialTouched,请改用 mapPropsToTouched。
initialValues: Values表单的初始字段值,Formik 将使这些值可供渲染方法组件作为 values 使用。
即使您的表单默认情况下为空,也必须使用初始值初始化所有字段,否则 React 将抛出一个错误,提示您已将输入从非受控更改为受控。
注意:高阶组件无法访问 initialValues,请改用 mapPropsToValues。
onReset?: (values: Values, formikBag: FormikBag) => void您可选的表单重置处理程序。它传递了表单的 values 和“FormikBag”。
onSubmit: (values: Values, formikBag: FormikBag) => void | Promise<any>您的表单提交处理程序。它传递了表单的 values 和“FormikBag”,其中包含一个对象,该对象包含注入的 props 和方法的子集(即所有名称以 set<Thing> 开头的方法 + resetForm)以及传递给包装组件的任何 props。
注意:errors、touched、status 和所有事件处理程序都不包含在 FormikBag 中。
重要:如果
onSubmit是异步的,则 Formik 将自动代表您将isSubmitting设置为false,一旦它已解析。这意味着您无需手动调用formikBag.setSubmitting(false)。但是,如果您的onSubmit函数是同步的,则需要自行调用setSubmitting(false)。
validate?: (values: Values) => FormikErrors<Values> | Promise<any>注意:我建议使用 validationSchema 和 Yup 进行验证。但是,validate 是一种无需依赖项的简单方法来验证您的表单。
使用函数验证表单的 values。此函数可以是
errors 对象。// Synchronous validationconst validate = values => {const 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;};
errors 的对象。// Async Validationconst sleep = ms => new Promise(resolve => setTimeout(resolve, ms));const validate = values => {return sleep(2000).then(() => {const errors = {};if (['admin', 'null', 'god'].includes(values.username)) {errors.username = 'Nice try';}// ...return errors;});};
validateOnBlur?: boolean默认值为 true。使用此选项在 blur 事件上运行验证。更具体地说,当调用 handleBlur、setFieldTouched 或 setTouched 时。
validateOnChange?: boolean默认值为 true。使用此选项告诉 Formik 在 change 事件和与 change 相关的事件上运行验证。更具体地说,当调用 handleChange、setFieldValue 或 setValues 时。
validateOnMount?: boolean默认值为 false。使用此选项告诉 Formik 在 <Formik /> 组件挂载和/或 initialValues 更改时运行验证。
validationSchema?: Schema | (() => Schema)一个 Yup 模式或返回 Yup 模式的函数。它用于验证。错误通过键映射到内部组件的 errors。它的键应与 values 的键匹配。