<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 中,
render
prop 也可以用于渲染。从 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>);
as
as?: string | React.ComponentType<FieldProps['field']>
React 组件或将要渲染的 HTML 元素的名称。也就是说,以下之一
input
select
textarea
自定义 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} />);
children
children?: 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>
component
component?: string | React.ComponentType<FieldProps>
React 组件或将要渲染的 HTML 元素的名称。也就是说,以下之一
input
select
textarea
自定义 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>);
innerRef
innerRef?: (el: React.HTMLElement<any> => void)
当您**不**使用自定义组件并且需要访问 Field
创建的基础 DOM 节点(例如,调用 focus
)时,请将回调传递给 innerRef
prop。
name
name: string
必填
Formik 状态中字段的名称。要访问嵌套对象或数组,name 也可以接受类似 lodash 的点路径,例如 social.facebook
或 friends[0].firstName
render
render?: (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>)}/>
validate
validate?: (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')
)。