Essential components for building forms with declarative syntax and automatic state management.
The main wrapper component that provides form state management and context to child components.
/**
* Main Formik wrapper component for form management
* @param props - Formik configuration and behavior options
* @returns JSX element containing form context and children
*/
function Formik<Values = any>(props: FormikConfig<Values>): JSX.Element;
interface FormikConfig<Values> {
/** Initial values of the form */
initialValues: Values;
/** Form submission handler */
onSubmit: (values: Values, formikHelpers: FormikHelpers<Values>) => void | Promise<any>;
/** Yup schema or validation function */
validationSchema?: any | (() => any);
/** Custom validation function */
validate?: (values: Values) => void | object | Promise<FormikErrors<Values>>;
/** Validate on input change (default: true) */
validateOnChange?: boolean;
/** Validate on input blur (default: true) */
validateOnBlur?: boolean;
/** Validate on component mount (default: false) */
validateOnMount?: boolean;
/** Whether initial form values are valid (default: false) */
isInitialValid?: boolean | ((props: any) => boolean);
/** Reset form when initialValues change (default: false) */
enableReinitialize?: boolean;
/** React children or render function */
children?: ((props: FormikProps<Values>) => React.ReactNode) | React.ReactNode;
/** Component to render */
component?: React.ComponentType<FormikProps<Values>>;
/** Render prop function */
render?: (props: FormikProps<Values>) => React.ReactNode;
/** Ref to access Formik instance */
innerRef?: React.Ref<FormikProps<Values>>;
/** Initial status value */
initialStatus?: any;
/** Initial errors object */
initialErrors?: FormikErrors<Values>;
/** Initial touched object */
initialTouched?: FormikTouched<Values>;
/** Reset handler */
onReset?: (values: Values, formikHelpers: FormikHelpers<Values>) => void;
}Usage Examples:
import { Formik, Form, Field } from "formik";
// With render prop
<Formik
initialValues={{ email: '', password: '' }}
onSubmit={(values, { setSubmitting }) => {
console.log(values);
setSubmitting(false);
}}
>
{({ isSubmitting }) => (
<Form>
<Field type="email" name="email" />
<Field type="password" name="password" />
<button type="submit" disabled={isSubmitting}>
Submit
</button>
</Form>
)}
</Formik>
// With children as function
<Formik
initialValues={{ name: '' }}
onSubmit={handleSubmit}
>
{(formik) => (
<form onSubmit={formik.handleSubmit}>
<input
name="name"
onChange={formik.handleChange}
value={formik.values.name}
/>
<button type="submit">Submit</button>
</form>
)}
</Formik>
// With component prop
const MyForm = ({ handleSubmit, values }) => (
<form onSubmit={handleSubmit}>
<Field name="email" />
<button type="submit">Submit</button>
</form>
);
<Formik
initialValues={{ email: '' }}
onSubmit={handleSubmit}
component={MyForm}
/>Generic field component that automatically connects to Formik context and handles common input patterns.
/**
* Generic field component with automatic form integration
* @param props - Field configuration and HTML attributes
* @returns JSX element connected to Formik state
*/
function Field<Val = any>(props: FieldProps<Val>): JSX.Element;
interface FieldProps<V = any, FormValues = any> {
/** Field name (required) */
name: string;
/** Field validation function */
validate?: FieldValidator;
/** Component to render */
component?: keyof JSX.IntrinsicElements | React.ComponentType<FieldProps<V, FormValues>>;
/** Render prop function */
render?: (props: FieldRenderProps<V, FormValues>) => React.ReactNode;
/** Children render function */
children?: (props: FieldRenderProps<V, FormValues>) => React.ReactNode;
/** HTML input type */
type?: string;
/** HTML attributes */
[key: string]: any;
}
interface FieldRenderProps<V = any, FormValues = any> {
field: FieldInputProps<V>;
form: FormikProps<FormValues>;
meta: FieldMetaProps<V>;
}
interface FieldInputProps<Value> {
/** Field value */
value: Value;
/** Field name */
name: string;
/** Multiple select flag */
multiple?: boolean;
/** Checked state for checkboxes/radios */
checked?: boolean;
/** Change event handler */
onChange: (e: React.ChangeEvent<any>) => void;
/** Blur event handler */
onBlur: (e: React.FocusEvent<any>) => void;
}
interface FieldMetaProps<Value> {
/** Field value */
value: Value;
/** Field error message */
error?: string;
/** Whether field has been touched */
touched: boolean;
/** Initial field value */
initialValue?: Value;
/** Initial touched state */
initialTouched: boolean;
/** Initial error message */
initialError?: string;
}Usage Examples:
// Basic input field
<Field name="email" type="email" placeholder="Email" />
// With custom component
<Field name="message" component="textarea" rows={4} />
// With render prop
<Field name="color">
{({ field, form, meta }) => (
<div>
<input type="color" {...field} />
{meta.touched && meta.error && (
<div className="error">{meta.error}</div>
)}
</div>
)}
</Field>
// With validation
<Field
name="age"
type="number"
validate={value => {
if (!value) return 'Required';
if (value < 18) return 'Must be 18 or older';
}}
/>
// Custom component
const MyInput = ({ field, form, ...props }) => (
<input {...field} {...props} />
);
<Field name="username" component={MyInput} />HTML form wrapper that automatically connects to Formik's submit and reset handlers.
/**
* HTML form wrapper with automatic Formik integration
* @param props - HTML form attributes
* @returns form element with integrated handlers
*/
const Form: React.ForwardRefExoticComponent<FormProps & React.RefAttributes<HTMLFormElement>>;
interface FormProps extends Omit<React.FormHTMLAttributes<HTMLFormElement>, 'onSubmit' | 'onReset'> {
children?: React.ReactNode;
}Usage Examples:
import { Formik, Form, Field } from "formik";
<Formik initialValues={{ name: '' }} onSubmit={handleSubmit}>
<Form>
<Field name="name" />
<button type="submit">Submit</button>
<button type="reset">Reset</button>
</Form>
</Formik>
// With custom props
<Formik initialValues={{ data: '' }} onSubmit={handleSubmit}>
<Form className="my-form" noValidate>
<Field name="data" />
<button type="submit">Submit</button>
</Form>
</Formik>Performance-optimized field component that only re-renders when its specific field changes, ideal for large forms.
/**
* Performance-optimized field component
* Only re-renders when its specific field changes
* @param props - FastField configuration identical to Field
* @returns JSX element with optimized rendering
*/
function FastField<V = any>(props: FastFieldProps<V>): JSX.Element;
interface FastFieldProps<V = any> {
/** Field name (required) */
name: string;
/** Field validation function */
validate?: FieldValidator;
/** Component to render */
component?: keyof JSX.IntrinsicElements | React.ComponentType<any>;
/** Render prop function */
render?: (props: FieldRenderProps<V>) => React.ReactNode;
/** Children render function */
children?: (props: FieldRenderProps<V>) => React.ReactNode;
/** When true, field will re-render on any form state change */
shouldUpdate?: (nextProps: FastFieldProps<V>, props: FastFieldProps<V>) => boolean;
/** HTML attributes */
[key: string]: any;
}Usage Examples:
import { Formik, Form, FastField } from "formik";
// Use FastField for better performance in large forms
<Formik initialValues={{ name: '', email: '', bio: '' }} onSubmit={handleSubmit}>
<Form>
<FastField name="name" placeholder="Name" />
<FastField name="email" type="email" placeholder="Email" />
<FastField name="bio" component="textarea" />
<button type="submit">Submit</button>
</Form>
</Formik>
// With custom shouldUpdate logic
<FastField
name="independentField"
shouldUpdate={(next, prev) => {
// Only update if this field's value or error changes
return next.name !== prev.name;
}}
/>
// With render prop (same API as Field)
<FastField name="priority">
{({ field, form, meta }) => (
<select {...field}>
<option value="low">Low</option>
<option value="medium">Medium</option>
<option value="high">High</option>
</select>
)}
</FastField>Hook for creating custom field components with full Formik integration.
/**
* Hook for field state management and helpers
* @param props - Field name or configuration object
* @returns Tuple of field props, meta props, and helper functions
*/
function useField<Val = any>(
props: string | FieldHookConfig<Val>
): [FieldInputProps<Val>, FieldMetaProps<Val>, FieldHelperProps<Val>];
interface FieldHookConfig<T> {
/** Field name */
name: string;
/** Field validation function */
validate?: FieldValidator;
/** HTML input type */
type?: string;
/** HTML attributes */
[key: string]: any;
}
interface FieldHelperProps<Value> {
/** Set field value */
setValue: (value: Value, shouldValidate?: boolean) => Promise<void | FormikErrors<Value>>;
/** Set field touched state */
setTouched: (value: boolean, shouldValidate?: boolean) => Promise<void | FormikErrors<Value>>;
/** Set field error */
setError: (value: string | undefined) => void;
}Usage Examples:
import { useField } from "formik";
const MyTextInput = ({ label, ...props }) => {
const [field, meta, helpers] = useField(props);
return (
<div>
<label htmlFor={props.id || props.name}>{label}</label>
<input {...field} {...props} />
{meta.touched && meta.error ? (
<div className="error">{meta.error}</div>
) : null}
</div>
);
};
// Usage in form
<Formik initialValues={{ email: '' }} onSubmit={handleSubmit}>
<Form>
<MyTextInput
label="Email Address"
name="email"
type="email"
placeholder="jane@formik.com"
/>
</Form>
</Formik>
// With custom validation
const ValidatedInput = (props) => {
const [field, meta, helpers] = useField({
...props,
validate: value => {
if (!value) return 'Required';
if (value.length < 3) return 'Too short';
}
});
return (
<div>
<input {...field} {...props} />
{meta.error && <span>{meta.error}</span>}
</div>
);
};