or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

field.mdform-spy.mdform.mdhooks.mdindex.mdtypescript.md
tile.json

tessl/npm-react-final-form

High performance subscription-based form state management for React

Workspace
tessl
Visibility
Public
Created
Last updated
Describes
npmpkg:npm/react-final-form@7.0.x

To install, run

npx @tessl/cli install tessl/npm-react-final-form@7.0.0

index.mddocs/

React Final Form

React Final Form is a high-performance, subscription-based form state management library for React applications. Built as a thin wrapper around Final Form, it provides efficient form handling through the Observer pattern with zero dependencies that affect bundle size and a tiny 3.0k gzipped footprint.

Package Information

  • Package Name: react-final-form
  • Package Type: npm
  • Language: TypeScript
  • Installation: npm install react-final-form

Core Imports

import { 
  Form, 
  Field, 
  FormSpy, 
  useForm, 
  useField, 
  useFormState,
  withTypes,
  version,
  all
} from "react-final-form";

// Import types from react-final-form
import type { 
  FormProps, 
  FieldProps, 
  FormSpyProps,
  FieldRenderProps,
  FormRenderProps,
  UseFieldConfig,
  UseFormStateParams,
  ReactContext,
  FormSpyPropsWithForm,
  FieldInputProps,
  RenderableProps,
  SubmitEvent,
  UseFieldAutoConfig
} from "react-final-form";

// Import types from final-form (peer dependency)
import type {
  FormApi,
  FormState,
  FieldState,
  FormSubscription,
  FieldSubscription,
  Config,
  Decorator,
  FieldValidator
} from "final-form";

For CommonJS:

const { 
  Form, 
  Field, 
  FormSpy, 
  useForm, 
  useField, 
  useFormState,
  withTypes,
  version,
  all
} = require("react-final-form");

Basic Usage

import React from "react";
import { Form, Field } from "react-final-form";

interface FormValues {
  firstName: string;
  lastName: string;
  email: string;
}

const onSubmit = (values: FormValues) => {
  console.log(values);
};

function MyForm() {
  return (
    <Form<FormValues>
      onSubmit={onSubmit}
      render={({ handleSubmit, form, submitting, pristine, values }) => (
        <form onSubmit={handleSubmit}>
          <Field name="firstName">
            {({ input, meta }) => (
              <div>
                <label>First Name</label>
                <input {...input} type="text" placeholder="First Name" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>
          
          <Field name="email">
            {({ input, meta }) => (
              <div>
                <label>Email</label>
                <input {...input} type="email" placeholder="Email" />
                {meta.error && meta.touched && <span>{meta.error}</span>}
              </div>
            )}
          </Field>
          
          <button type="submit" disabled={submitting}>
            Submit
          </button>
          <button
            type="button"
            onClick={form.reset}
            disabled={submitting || pristine}
          >
            Reset
          </button>
        </form>
      )}
    />
  );
}

Architecture

React Final Form is built around several key components:

  • Form Component: Root form wrapper that provides form context and manages form state
  • Field Component: Individual field components that subscribe to specific field state
  • Hooks API: Modern React hooks for accessing form and field state
  • Subscription System: Opt-in subscriptions ensure only components requiring updates are re-rendered
  • Render Props: Flexible rendering patterns supporting both render props and children functions
  • Type Safety: Full TypeScript support with generic type preservation

Capabilities

Form Management

Core form wrapper component that provides form context, state management, and submission handling with efficient subscription-based updates.

const Form: <FormValues = Record<string, any>>(
  props: FormProps<FormValues>
) => React.ReactElement;

interface FormProps<FormValues = Record<string, any>>
  extends Config<FormValues>,
    RenderableProps<FormRenderProps<FormValues>> {
  subscription?: FormSubscription;
  decorators?: Decorator<FormValues>[];
  form?: FormApi<FormValues>;
  initialValuesEqual?: (
    a?: Record<string, any>,
    b?: Record<string, any>
  ) => boolean;
}

interface FormRenderProps<FormValues = Record<string, any>>
  extends FormState<FormValues> {
  handleSubmit: (
    event?: SubmitEvent
  ) => Promise<Record<string, any> | undefined> | undefined;
  form: FormApi<FormValues>;
}

Form Component

Field Management

Individual field components with subscription-based state management, validation, formatting, and parsing capabilities.

const Field: <
  FieldValue = any,
  T extends HTMLElement = HTMLElement,
  FormValues = Record<string, any>
>(
  props: FieldProps<FieldValue, T, FormValues>
) => React.ReactElement;

interface FieldProps<
  FieldValue = any,
  T extends HTMLElement = HTMLElement,
  FormValues = Record<string, any>
> extends UseFieldConfig,
    Omit<RenderableProps<FieldRenderProps<FieldValue, T>>, "children"> {
  name: string;
  children?: RenderableProps<FieldRenderProps<FieldValue, T>>["children"];
  [key: string]: any;
}

interface FieldRenderProps<
  FieldValue = any,
  T extends HTMLElement = HTMLElement,
  FormValues = any
> {
  input: FieldInputProps<FieldValue, T>;
  meta: {
    active?: boolean;
    data?: Record<string, any>;
    dirty?: boolean;
    dirtySinceLastSubmit?: boolean;
    error?: any;
    initial?: any;
    invalid?: boolean;
    length?: number;
    modified?: boolean;
    modifiedSinceLastSubmit?: boolean;
    pristine?: boolean;
    submitError?: any;
    submitFailed?: boolean;
    submitSucceeded?: boolean;
    submitting?: boolean;
    touched?: boolean;
    valid?: boolean;
    validating?: boolean;
    visited?: boolean;
  };
}

Field Component

Form State Observation

FormSpy component for observing form state changes without rendering form fields, perfect for external components that need form state updates.

const FormSpy: <FormValues = Record<string, any>>(
  props: FormSpyProps<FormValues>
) => React.ReactElement;

interface FormSpyProps<FormValues = Record<string, any>>
  extends UseFormStateParams<FormValues>,
    RenderableProps<FormSpyRenderProps<FormValues>> {}

interface FormSpyRenderProps<FormValues = Record<string, any>>
  extends FormState<FormValues> {
  form: FormApi<FormValues>;
}

Form Spy

Hooks API

Modern React hooks for accessing form context, field state, and form state with customizable subscriptions and full TypeScript support.

function useForm<FormValues = Record<string, any>>(
  componentName?: string
): FormApi<FormValues>;

function useField<
  FieldValue = any,
  T extends HTMLElement = HTMLElement,
  FormValues = Record<string, any>
>(
  name: string,
  config?: UseFieldConfig
): FieldRenderProps<FieldValue, T, FormValues>;

function useFormState<FormValues = Record<string, any>>(
  params?: UseFormStateParams<FormValues>
): FormState<FormValues>;

Hooks API

TypeScript Integration

Utility functions and type helpers for enhanced TypeScript support with strongly typed form and field components.

function withTypes<FormValues = Record<string, any>>(): {
  Form: React.ComponentType<FormProps<FormValues>>;
  FormSpy: React.ComponentType<FormSpyProps<FormValues>>;
};

const version: string;

const all: FormSubscription;

TypeScript Support

Core Types

interface FieldInputProps<
  FieldValue = any,
  T extends HTMLElement = HTMLElement
> {
  name: string;
  onBlur: (event?: React.FocusEvent<T>) => void;
  onChange: (event: React.ChangeEvent<T> | any) => void;
  onFocus: (event?: React.FocusEvent<T>) => void;
  value: FieldValue;
  checked?: boolean;
  multiple?: boolean;
  type?: string;
}

interface RenderableProps<T> {
  component?: React.ComponentType<any> | SupportedInputs;
  children?: ((props: T) => React.ReactNode) | React.ReactNode;
  render?: (props: T) => React.ReactNode;
}

interface SubmitEvent {
  preventDefault?: () => void;
  stopPropagation?: () => void;
}

interface UseFormStateParams<FormValues = Record<string, any>> {
  onChange?: (formState: FormState<FormValues>) => void;
  subscription?: FormSubscription;
}

interface UseFieldConfig extends UseFieldAutoConfig {
  subscription?: FieldSubscription;
}

interface UseFieldAutoConfig {
  afterSubmit?: () => void;
  allowNull?: boolean;
  beforeSubmit?: () => void | false;
  component?: RenderableProps<any>["component"];
  data?: Record<string, any>;
  defaultValue?: any;
  format?: (value: any, name: string) => any;
  formatOnBlur?: boolean;
  initialValue?: any;
  isEqual?: (a: any, b: any) => boolean;
  multiple?: boolean;
  parse?: (value: any, name: string) => any;
  type?: string;
  validate?: FieldValidator<any>;
  validateFields?: string[];
  value?: any;
}

interface ReactContext<FormValues = Record<string, any>> {
  reactFinalForm: FormApi<FormValues>;
}

interface FormSpyPropsWithForm<FormValues = Record<string, any>>
  extends FormSpyProps<FormValues> {
  reactFinalForm: FormApi<FormValues>;
}

type SupportedInputs = "input" | "select" | "textarea";