or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

context-integration.mdcore-components.mderror-handling.mdfield-arrays.mdform-state-management.mdindex.md
tile.json

tessl/npm-formik

Build forms in React, without the tears

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/formik@2.4.x

To install, run

npx @tessl/cli install tessl/npm-formik@2.4.0

index.mddocs/

Formik

Formik is a comprehensive React form library that simplifies building, validating, and handling forms in React applications. It provides a declarative API for managing form state, validation, and error handling through render props, hooks, and higher-order components. The library offers seamless integration with popular validation libraries like Yup, supports both synchronous and asynchronous validation, and handles complex form scenarios including nested objects, arrays, and dynamic fields.

Package Information

  • Package Name: formik
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install formik

Core Imports

import { Formik, Field, Form, useFormik } from "formik";

For CommonJS:

const { Formik, Field, Form, useFormik } = require("formik");

Additional imports for advanced functionality:

import { 
  FieldArray, 
  ErrorMessage, 
  FastField,
  withFormik,
  useFormikContext,
  FormikProvider
} from "formik";

Basic Usage

import { Formik, Field, Form, ErrorMessage } from "formik";
import * as Yup from "yup";

interface FormValues {
  email: string;
  password: string;
}

const LoginSchema = Yup.object().shape({
  email: Yup.string().email('Invalid email').required('Required'),
  password: Yup.string().min(6, 'Too Short!').required('Required'),
});

const LoginForm = () => (
  <Formik
    initialValues={{ email: '', password: '' }}
    validationSchema={LoginSchema}
    onSubmit={(values, { setSubmitting }) => {
      console.log(values);
      setSubmitting(false);
    }}
  >
    <Form>
      <Field name="email" type="email" placeholder="Email" />
      <ErrorMessage name="email" component="div" />
      
      <Field name="password" type="password" placeholder="Password" />
      <ErrorMessage name="password" component="div" />
      
      <button type="submit">Submit</button>
    </Form>
  </Formik>
);

Alternative hook-based approach:

import { useFormik } from "formik";

const LoginForm = () => {
  const formik = useFormik({
    initialValues: { email: '', password: '' },
    validationSchema: LoginSchema,
    onSubmit: values => {
      console.log(values);
    },
  });

  return (
    <form onSubmit={formik.handleSubmit}>
      <input
        id="email"
        name="email"
        type="email"
        onChange={formik.handleChange}
        onBlur={formik.handleBlur}
        value={formik.values.email}
      />
      {formik.touched.email && formik.errors.email ? (
        <div>{formik.errors.email}</div>
      ) : null}
      
      <button type="submit">Submit</button>
    </form>
  );
};

Architecture

Formik is built around several key architectural patterns:

  • Component-based API: <Formik>, <Field>, and <Form> components provide declarative form management
  • Hook-based API: useFormik and useField hooks for functional component integration
  • Context System: React Context propagates form state throughout component trees
  • Render Props Pattern: Flexible rendering via function-as-children or render prop patterns
  • Validation System: Support for sync/async validation with schema libraries like Yup
  • State Management: Centralized form state with optimized re-rendering strategies
  • Helper Functions: Extensive utilities for form manipulation and validation

Capabilities

Core Components

Essential components for building forms with declarative syntax and automatic state management.

function Formik<Values = any>(props: FormikConfig<Values>): JSX.Element;

interface FormikConfig<Values> {
  initialValues: Values;
  onSubmit: (values: Values, formikHelpers: FormikHelpers<Values>) => void | Promise<any>;
  validationSchema?: any;
  validate?: (values: Values) => void | object | Promise<FormikErrors<Values>>;
  validateOnChange?: boolean;
  validateOnBlur?: boolean;
  validateOnMount?: boolean;
  isInitialValid?: boolean | ((props: any) => boolean);
  enableReinitialize?: boolean;
  children?: ((props: FormikProps<Values>) => React.ReactNode) | React.ReactNode;
  component?: React.ComponentType<FormikProps<Values>>;
  render?: (props: FormikProps<Values>) => React.ReactNode;
  innerRef?: React.Ref<FormikProps<Values>>;
  initialStatus?: any;
  initialErrors?: FormikErrors<Values>;
  initialTouched?: FormikTouched<Values>;
  onReset?: (values: Values, formikHelpers: FormikHelpers<Values>) => void;
}

Core Components

Form State Management

Hook-based form state management for functional components, providing complete form control without component wrappers.

function useFormik<Values extends FormikValues = FormikValues>(
  config: FormikConfig<Values>
): FormikProps<Values>;

interface FormikProps<Values> {
  values: Values;
  errors: FormikErrors<Values>;
  touched: FormikTouched<Values>;
  isSubmitting: boolean;
  isValidating: boolean;
  status?: any;
  submitCount: number;
  dirty: boolean;
  isValid: boolean;
  initialValues: Values;
  handleSubmit: (e?: React.FormEvent<HTMLFormElement>) => void;
  handleReset: (e?: React.SyntheticEvent<any>) => void;
  handleBlur: (e: React.FocusEvent<any>) => void;
  handleChange: (e: React.ChangeEvent<any>) => void;
  setFieldValue: (field: string, value: any, shouldValidate?: boolean) => Promise<void | FormikErrors<Values>>;
  setFieldError: (field: string, message: string | undefined) => void;
  setFieldTouched: (field: string, isTouched?: boolean, shouldValidate?: boolean) => Promise<void | FormikErrors<Values>>;
  validateForm: (values?: any) => Promise<FormikErrors<Values>>;
  validateField: (field: string) => Promise<void> | Promise<string | undefined>;
  resetForm: (nextState?: Partial<FormikState<Values>>) => void;
  submitForm: () => Promise<void>;
}

Form State Management

Dynamic Field Arrays

Components and utilities for managing dynamic arrays of form fields with helper methods for manipulation.

function FieldArray(props: FieldArrayConfig): JSX.Element;

interface FieldArrayConfig {
  name: string;
  children?: (props: FieldArrayRenderProps) => React.ReactNode;
  component?: React.ComponentType<FieldArrayRenderProps>;
  render?: (props: FieldArrayRenderProps) => React.ReactNode;
}

interface ArrayHelpers<T = any> {
  push: (obj: T) => void;
  pop: () => T | undefined;
  remove: (index: number) => T | undefined;
  insert: (index: number, value: T) => void;
  unshift: (value: T) => number;
  move: (from: number, to: number) => void;
  swap: (indexA: number, indexB: number) => void;
  replace: (index: number, value: T) => void;
}

Dynamic Field Arrays

Error Handling

Components and patterns for displaying validation errors with flexible rendering options.

function ErrorMessage(props: ErrorMessageProps): JSX.Element | null;

interface ErrorMessageProps {
  name: string;
  component?: React.ComponentType<any> | string;
  children?: ((error: string) => React.ReactNode);
  render?: (error: string) => React.ReactNode;
  className?: string;
}

Error Handling

Context & Integration

React Context providers and higher-order components for advanced integration patterns and legacy component support.

function useFormikContext<Values>(): FormikContextType<Values>;

function withFormik<OuterProps, Values, Payload = Values>(
  config: WithFormikConfig<OuterProps, Values, Payload>
): ComponentDecorator<OuterProps, OuterProps & InjectedFormikProps<OuterProps, Values>>;

const FormikProvider: React.Provider<FormikContextType<any>>;
const FormikConsumer: React.Consumer<FormikContextType<any>>;

Context & Integration

Types

interface FormikValues {
  [field: string]: any;
}

type FormikErrors<Values> = {
  [K in keyof Values]?: Values[K] extends any[]
    ? Values[K][number] extends object
      ? FormikErrors<Values[K][number]>[] | string | string[]
      : string | string[]
    : Values[K] extends object
    ? FormikErrors<Values[K]>
    : string;
};

type FormikTouched<Values> = {
  [K in keyof Values]?: Values[K] extends any[]
    ? Values[K][number] extends object
      ? FormikTouched<Values[K][number]>[]
      : boolean
    : Values[K] extends object
    ? FormikTouched<Values[K]>
    : boolean;
};

interface FormikState<Values> {
  values: Values;
  errors: FormikErrors<Values>;
  touched: FormikTouched<Values>;
  isSubmitting: boolean;
  isValidating: boolean;
  status?: any;
  submitCount: number;
}

interface FormikComputedProps<Values> {
  readonly dirty: boolean;
  readonly isValid: boolean;
  readonly initialValues: Values;
  readonly initialErrors: FormikErrors<Values>;
  readonly initialTouched: FormikTouched<Values>;
  readonly initialStatus?: any;
}

interface FormikHelpers<Values> {
  setStatus: (status?: any) => void;
  setErrors: (errors: FormikErrors<Values>) => void;
  setSubmitting: (isSubmitting: boolean) => void;
  setTouched: (touched: FormikTouched<Values>, shouldValidate?: boolean) => Promise<void | FormikErrors<Values>>;
  setValues: (values: React.SetStateAction<Values>, shouldValidate?: boolean) => Promise<void | FormikErrors<Values>>;
  setFieldValue: (field: string, value: any, shouldValidate?: boolean) => Promise<void | FormikErrors<Values>>;
  setFieldError: (field: string, message: string | undefined) => void;
  setFieldTouched: (field: string, isTouched?: boolean, shouldValidate?: boolean) => Promise<void | FormikErrors<Values>>;
  validateForm: (values?: any) => Promise<FormikErrors<Values>>;
  validateField: (field: string) => Promise<void> | Promise<string | undefined>;
  resetForm: (nextState?: Partial<FormikState<Values>>) => void;
  submitForm: () => Promise<void>;
  setFormikState: (f: FormikState<Values> | ((prevState: FormikState<Values>) => FormikState<Values>), cb?: () => void) => void;
}

type FieldValidator = (value: any) => string | void | Promise<string | void>;

interface FieldConfig<V = any> {
  name: string;
  validate?: FieldValidator;
  [key: string]: any;
}

interface SharedRenderProps<T> {
  component?: keyof JSX.IntrinsicElements | React.ComponentType<T | void>;
  render?: (props: T) => React.ReactNode;
  children?: (props: T) => React.ReactNode;
}

type GenericFieldHTMLAttributes = 
  | JSX.IntrinsicElements['input']
  | JSX.IntrinsicElements['select'] 
  | JSX.IntrinsicElements['textarea'];

interface FormikRegistration {
  registerField: (name: string, fns: { validate?: FieldValidator }) => void;
  unregisterField: (name: string) => void;
}

interface FieldMetaProps<Value> {
  value: Value;
  error?: string;
  touched: boolean;
  initialValue?: Value;
  initialTouched: boolean;
  initialError?: string;
}

interface FieldHelperProps<Value> {
  setValue: (value: Value, shouldValidate?: boolean) => Promise<void | FormikErrors<Value>>;
  setTouched: (value: boolean, shouldValidate?: boolean) => Promise<void | FormikErrors<Value>>;
  setError: (value: string | undefined) => void;
}

interface FieldInputProps<Value> {
  value: Value;
  name: string;
  multiple?: boolean;
  checked?: boolean;
  onChange: (e: React.ChangeEvent<any>) => void;
  onBlur: (e: React.FocusEvent<any>) => void;
}