useField()
useField
is a custom React hook that will automagically help you hook up inputs to Formik. You can and should use it to build your own custom input primitives. There are 2 ways to use it.
#
Exampleimport React from 'react';import { useField, Form, FormikProps, Formik } from 'formik';
interface Values { firstName: string; lastName: string; email: string;}
const MyTextField = ({ label, ...props }) => { const [field, meta, helpers] = useField(props); return ( <> <label> {label} <input {...field} {...props} /> </label> {meta.touched && meta.error ? ( <div className="error">{meta.error}</div> ) : null} </> );};
const Example = () => ( <div> <h1>My Form</h1> <Formik initialValues={{ email: '', firstName: 'red', lastName: '', }} onSubmit={(values, actions) => { setTimeout(() => { alert(JSON.stringify(values, null, 2)); actions.setSubmitting(false); }, 1000); }} > {(props: FormikProps<Values>) => ( <Form> <MyTextField name="firstName" type="text" label="First Name" /> <MyTextField name="lastName" type="text" label="Last Name" /> <MyTextField name="email" type="email" label="Email" /> <button type="submit">Submit</button> </Form> )} </Formik> </div>);
Reference
useField<Value = any>(name: string | FieldHookConfig<Value>): [FieldInputProps<Value>, FieldMetaProps<Value>, FieldHelperProps]
#
A custom React Hook that returns a 3-tuple (an array with three elements) containing FieldProps
, FieldMetaProps
and FieldHelperProps
. It accepts either a string of a field name or an object as an argument. The object must at least contain a name
key. This object is a subset of the props that you would pass to <Field>
and the values and functions in FieldProps
will mimic the behavior of <Field>
exactly. This is useful, and generally preferred, since it allows you to take advantage of Formik's checkbox, radio, and multiple select behavior when the object contains the relevant key/values (e.g. type: 'checkbox'
, multiple: true
, etc.).
FieldMetaProps
contains computed values about the field which can be used to style or otherwise change the field. FieldHelperProps
contains helper functions that allow you to imperatively change a field's values.
import React from 'react';import { useField } from 'formik';
function MyTextField(props) { // this will return field props for an <input /> const [field, meta, helpers] = useField(props.name); return ( <> <input {...field} {...props} /> {meta.error && meta.touched && <div>{meta.error}</div>} </> );}
function MyInput(props) { // this will return field exactly like <Field>{({ field }) => ... }</Field> const [field, meta] = useField(props); return ( <> <input {...field} {...props} /> {meta.error && meta.touched && <div>{meta.error}</div>} </> );}
function MyOtherComponent(props) { // This isn't an input, so instead of using the values in 'field' directly, // we'll use 'meta' and 'helpers'. const [field, meta, helpers] = useField(props.name);
const { value } = meta; const { setValue } = helpers;
const isSelected = v => (v === value ? 'selected' : '');
return ( <div className="itemsPerPage"> <button onClick={() => setValue(5)} className={isSelected(5)}> 5 </button> <button onClick={() => setValue(10)} className={isSelected(10)}> 10 </button> <button onClick={() => setValue(25)} className={isSelected(25)}> 25 </button> </div> );}
FieldHookConfig<Value>
#
This object is a subset of the props that you would pass to <Field>
. It contains:
name: string
- The name of the fieldvalidate?: (value: any) => undefined | string | Promise<any>
- See the documentation for<Field>
type?: string
- The type of the HTML input (text
,number
and etc.)multiple?: boolean
- Whether or not the multiple values can be selected.value?: string
- Works only for inputs of typecheckbox
andradio
. When a form is submitted, checkboxes and radios are submitted with the providedvalue
. Read more about it on MDN.
FieldInputProps<Value>
#
An object that contains:
name: string
- The name of the fieldchecked?: boolean
- Whether or not the input is checked, this is only defined ifuseField
is passed an object with aname
,type: 'checkbox'
ortype: 'radio'
.onBlur: () => void
- A blur event handleronChange: (e: React.ChangeEvent<any>) => void
- A change event handlervalue: Value
- The field's value (plucked out ofvalues
) or, if it is a checkbox or radio input, then potentially thevalue
passed intouseField
.multiple?: boolean
- Whether or not the multiple values can be selected. This is only ever defined whenuseField
is passed an object withmultiple: true
FieldMetaProps<Value>
#
An object that contains relevant computed metadata about a field. More specifically,
error?: string
- The field's error message (plucked out oferrors
)initialError?: string
- The field's initial error if the field is present ininitialErrors
(plucked out ofinitialErrors
)initialTouched: boolean
- The field's initial value if the field is present ininitialTouched
(plucked out ofinitialTouched
)initialValue?: Value
- The field's initial value if the field is given a value ininitialValues
(plucked out ofinitialValues
)touched: boolean
- Whether the field has been visited (plucked out oftouched
)value: any
- The field's value (plucked out ofvalues
)
FieldHelperProps
#
An object that contains helper functions which you can use to imperatively change the value, error value or touched status for the field in question. This is useful for components which need to change a field's status directly, without triggering change or blur events.
setValue(value: any, shouldValidate?: boolean): void
- A function to change the field's value. Calling this will trigger validation to run ifvalidateOnChange
is set totrue
(which it is by default). You can also explicitly prevent/skip validation by passing a second argument asfalse
.setTouched(value: boolean, shouldValidate?: boolean): void
- A function to change the field's touched status. Calling this will trigger validation to run ifvalidateOnBlur
is set totrue
(which it is by default). You can also explicitly prevent/skip validation by passing a second argument asfalse
.setError(value: any): void
- A function to change the field's error value