<欄位 />
會自動將輸入連接到 Formik。它使用 name
屬性來與 Formik 狀態匹配。 <欄位 />
預設為 HTML <input />
元素。
使用 <欄位>
渲染內容的方式有幾種。
<欄位 as>
<欄位 children>
<欄位 component>
<欄位 render>
as
可以是 React 組件或要渲染的 HTML 元素的名稱。Formik 會自動將 name
屬性指定的欄位的 onChange
、onBlur
、name
和 value
屬性注入到(自定義)組件中。
children
可以是元素陣列(例如 <Field as="select">
情況下的 <option>
)或回調函數(又稱渲染屬性)。渲染屬性是一個包含以下內容的物件:
field
:一個包含欄位的 onChange
、onBlur
、name
和 value
的物件(請參閱 FieldInputProps
)form
:Formik 包meta
:一個包含關於欄位的元數據(即 value
、touched
、error
和 initialValue
)的物件(請參閱 FieldMetaProps
)component
可以是 React 組件或要渲染的 HTML 元素的名稱。所有額外的屬性都將被傳遞。
在 Formik 0.9 到 1.x 中,
render
屬性也可用於渲染。自 2.x 起已棄用。雖然程式碼仍然存在於<欄位>
中,但使用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
,以及直接傳遞給 <欄位>
的任何其他屬性。
預設值為 '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?: string | React.ComponentType<FieldProps>
React 組件或要渲染的 HTML 元素的名稱。也就是以下其中之一:
input
select
textarea
自定義 React 組件將會收到 `FieldProps`,它與 `<欄位 render>` 的 `render` 屬性參數相同,加上直接傳遞給 `<欄位>` 的任何其他屬性。
預設值為 '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)
當您**不**使用自定義組件且需要訪問由 `欄位` 建立的底層 DOM 節點時(例如呼叫 `focus`),請將回調傳遞給 `innerRef` 屬性。
name
name: string
必填
Formik 狀態中欄位的名稱。要訪問巢狀物件或陣列,名稱也可以接受類似 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` 屬性來執行獨立的欄位級驗證。該函數將遵循 `<欄位>` 的父級 `<Formik>` / `withFormik` 中指定的 `validateOnBlur` 和 `validateOnChange` 設定/屬性。此函數可以是同步的或非同步的:
同步:如果無效,則返回包含錯誤訊息的 `string` 或返回 `undefined`。
非同步:返回一個解析包含錯誤訊息的 `string` 的 Promise。這類似於 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')`)。