<Field /> 会自动将输入连接到 Formik。它使用 name 属性与 Formik 状态匹配。<Field /> 默认情况下会渲染为 HTML 的 <input /> 元素。
有几种不同的方法可以使用 <Field> 进行渲染。
<Field as><Field children><Field component><Field render>as 可以是 React 组件,也可以是将要渲染的 HTML 元素的名称。Formik 会自动注入由 name 属性指定的字段的 onChange、onBlur、name 和 value 属性到(自定义)组件中。
children 可以是元素数组(例如,在 <Field as="select"> 的情况下为 <option>),也可以是回调函数(也称为渲染 prop)。渲染 prop 是一个包含以下内容的对象
field:一个包含字段的 onChange、onBlur、name 和 value 的对象(参见 FieldInputProps)form:Formik 包meta:一个包含字段元数据(即 value、touched、error 和 initialValue)的对象(参见 FieldMetaProps)component 可以是 React 组件,也可以是将要渲染的 HTML 元素的名称。所有其他 props 都将被传递。
在 Formik 0.9 到 1.x 中,
renderprop 也可以用于渲染。从 2.x 开始它已被弃用。虽然代码仍然存在于<Field>中,但使用render会在控制台中显示警告。
import React from 'react';import { Field, Form, Formik, FormikProps } from 'formik';const MyInput = ({ field, form, ...props }) => {return <input {...field} {...props} />;};const Example = () => (<div><h1>My Form</h1><FormikinitialValues={{ email: '', color: 'red', firstName: '', lastName: '' }}onSubmit={(values, actions) => {setTimeout(() => {alert(JSON.stringify(values, null, 2));actions.setSubmitting(false);}, 1000);}}>{(props: FormikProps<any>) => (<Form><Field type="email" name="email" placeholder="Email" /><Field as="select" name="color"><option value="red">Red</option><option value="green">Green</option><option value="blue">Blue</option></Field><Field name="lastName">{({field, // { name, value, onChange, onBlur }form: { touched, errors }, // also values, setXXXX, handleXXXX, dirty, isValid, status, etc.meta,}) => (<div><input type="text" placeholder="Email" {...field} />{meta.touched && meta.error && (<div className="error">{meta.error}</div>)}</div>)}</Field><Field name="lastName" placeholder="Doe" component={MyInput} /><button type="submit">Submit</button></Form>)}</Formik></div>);
asas?: string | React.ComponentType<FieldProps['field']>
React 组件或将要渲染的 HTML 元素的名称。也就是说,以下之一
inputselecttextarea自定义 React 组件将被传递 onChange、onBlur、name 和 value 以及直接传递给 <Field> 的任何其他 props。
默认为 'input'(因此默认情况下会渲染 <input>)
// Renders an HTML <input> by default<Field name="lastName" placeholder="Last Name"/>// Renders an HTML <select><Field name="color" as="select"><option value="red">Red</option><option value="green">Green</option><option value="blue">Blue</option></Field>// Renders a CustomInputComponent<Field name="firstName" as={CustomInputComponent} placeholder="First Name"/>const CustomInputComponent = (props) => (<input className="my-custom-input" type="text" {...props} />);
childrenchildren?: React.ReactNode | ((props: FieldProps) => React.ReactNode)
JSX 元素或回调函数。与 render 相同。
// Children can be JSX elements<Field name="color" as="select"><option value="red">Red</option><option value="green">Green</option><option value="blue">Blue</option></Field>// Or a callback function<Field name="firstName">{({ field, form, meta }) => (<div><input type="text" {...field} placeholder="First Name"/>{meta.touched &&meta.error && <div className="error">{meta.error}</div>}</div>)}</Field>
componentcomponent?: string | React.ComponentType<FieldProps>
React 组件或将要渲染的 HTML 元素的名称。也就是说,以下之一
inputselecttextarea自定义 React 组件将被传递 FieldProps,它与 <Field render> 的 render prop 参数相同,以及直接传递给 <Field> 的任何其他 props。
默认为 'input'(因此默认情况下会渲染 <input>)
// Renders an HTML <input> by default<Field name="lastName" placeholder="Last Name"/>// Renders an HTML <select><Field name="color" component="select"><option value="red">Red</option><option value="green">Green</option><option value="blue">Blue</option></Field>// Renders a CustomInputComponent<Field name="firstName" component={CustomInputComponent} placeholder="First Name"/>const CustomInputComponent = ({field, // { name, value, onChange, onBlur }form: { touched, errors }, // also values, setXXXX, handleXXXX, dirty, isValid, status, etc....props}) => (<div><input type="text" {...field} {...props} />{touched[field.name] &&errors[field.name] && <div className="error">{errors[field.name]}</div>}</div>);
innerRefinnerRef?: (el: React.HTMLElement<any> => void)
当您**不**使用自定义组件并且需要访问 Field 创建的基础 DOM 节点(例如,调用 focus)时,请将回调传递给 innerRef prop。
namename: string
必填
Formik 状态中字段的名称。要访问嵌套对象或数组,name 也可以接受类似 lodash 的点路径,例如 social.facebook 或 friends[0].firstName
renderrender?: (props: FieldProps) => React.ReactNode
在 2.x 中已弃用。请改用 children。
返回一个或多个 JSX 元素的函数。
// Renders an HTML <input> and passes FieldProps field property<Fieldname="firstName"render={({ field /* { name, value, onChange, onBlur } */ }) => (<input {...field} type="text" placeholder="firstName" />)}/>// Renders an HTML <input> and disables it while form is submitting<Fieldname="lastName"render={({ field, form: { isSubmitting } }) => (<input {...field} disabled={isSubmitting} type="text" placeholder="lastName" />)}/>// Renders an HTML <input> with custom error <div> element<Fieldname="lastName"render={({ field, form: { touched, errors } }) => (<div><input {...field} type="text" placeholder="lastName" />{touched[field.name] &&errors[field.name] && <div className="error">{errors[field.name]}</div>}</div>)}/>
validatevalidate?: (value: any) => undefined | string | Promise<any>
您可以通过将函数传递给 validate prop 来运行独立的字段级验证。该函数将遵守 <Field> 的父 <Formik> / withFormik 中指定的 validateOnBlur 和 validateOnChange 配置/prop。此函数可以是同步的也可以是异步的
同步:如果无效,则返回包含错误消息的 string 或返回 undefined。
异步:返回一个 Promise,该 Promise 解析包含错误消息的 string。这与 Formik 的 validate 类似,但它不是返回 errors 对象,而只是一个 string。
import React from 'react';import { Formik, Form, Field } from 'formik';// Synchronous validation functionconst validate = value => {let errorMessage;if (!/^[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,4}$/i.test(value)) {errorMessage = 'Invalid email address';}return errorMessage;};// Async validation functionconst sleep = ms => new Promise(resolve => setTimeout(resolve, ms));const validateAsync = value => {return sleep(2000).then(() => {if (['admin', 'null', 'god'].includes(value)) {return 'Nice try';}});};// example usageconst MyForm = () => (<FormikinitialValues={{ email: '', username: '' }}onSubmit={values => alert(JSON.stringify(values, null, 2))}>{({ errors, touched }) => (<Form><Field validate={validate} name="email" type="email" />{errors.email && touched.email ? <div>{errors.email}</div> : null}<Field validate={validateAsync} name="username" />{errors.username && touched.username ? (<div>{errors.username}</div>) : null}<button type="submit">Submit</button></Form>)}</Formik>);
注意:为了允许 i18n 库,validate 的 TypeScript 类型定义略微放宽,允许您返回 Function(例如 i18n('invalid'))。