CtrlK
BlogDocsLog inGet started
Tessl Logo

tessl/npm-final-form

Framework-agnostic, high-performance form state management library with subscription-based updates.

Pending
Quality

Pending

Does it follow best practices?

Impact

Pending

No eval scenarios have been run

SecuritybySnyk

Pending

The risk profile of this skill

Overview
Eval results
Files

state-management.mddocs/

State Management

Comprehensive form and field state management with subscription-based updates for optimal performance and minimal re-renders.

Capabilities

Form State Access

Methods for accessing and subscribing to form state changes.

interface FormApi<FormValues, InitialFormValues> {
  /** Get current form state synchronously */
  getState(): FormState<FormValues, InitialFormValues>;
  
  /** Subscribe to form state changes with selective subscription */
  subscribe(
    subscriber: FormSubscriber<FormValues, InitialFormValues>,
    subscription: FormSubscription
  ): Unsubscribe;
  
  /** Subscribe to form state with callback-based approach */
  subscribeFormState(
    onChange: () => void,
    subscription: FormSubscription
  ): Unsubscribe;
  
  /** Get a snapshot of current form state */
  getFormSnapshot(): FormState<FormValues, InitialFormValues>;
  
  /** Batch multiple operations to prevent multiple notifications */
  batch(fn: () => void): void;
}

Usage Examples:

import { createForm } from "final-form";

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

// Get current state
const currentState = form.getState();
console.log('Form is valid:', currentState.valid);

// Subscribe to specific form state properties
const unsubscribe = form.subscribe(
  (formState) => {
    console.log('Values changed:', formState.values);
    console.log('Form is dirty:', formState.dirty);
  },
  { values: true, dirty: true } // Only get notified of these changes
);

// Callback-based subscription
const unsubscribeCallback = form.subscribeFormState(
  () => {
    const snapshot = form.getFormSnapshot();
    console.log('Form state changed:', snapshot);
  },
  { valid: true, submitting: true }
);

// Batch operations to prevent multiple notifications
form.batch(() => {
  form.change('firstName', 'John');
  form.change('lastName', 'Doe');
  form.change('email', 'john@example.com');
  // Only one notification will be sent after all changes
});

Form State Interface

Complete form state object with all available properties.

interface FormState<
  FormValues = Record<string, any>,
  InitialFormValues extends Partial<FormValues> = Partial<FormValues>
> {
  /** Currently active (focused) field name */
  active?: keyof FormValues;
  
  /** Whether any field has been modified from initial values */
  dirty?: boolean;
  
  /** Object indicating which specific fields are dirty */
  dirtyFields?: { [key: string]: boolean };
  
  /** Which fields have been modified since last submit */
  dirtyFieldsSinceLastSubmit?: { [key: string]: boolean };
  
  /** Whether form has been modified since last submission */
  dirtySinceLastSubmit?: boolean;
  
  /** Form-level error (when using FORM_ERROR) */
  error?: any;
  
  /** Field-level validation errors */
  errors?: ValidationErrors;
  
  /** Whether form has submission errors */
  hasSubmitErrors?: boolean;
  
  /** Whether form has validation errors */
  hasValidationErrors?: boolean;
  
  /** Initial values provided at form creation */
  initialValues?: InitialFormValues;
  
  /** Whether form has any validation errors */
  invalid?: boolean;
  
  /** Object indicating which fields have been modified */
  modified?: { [key: string]: boolean };
  
  /** Whether form has been modified since last submission */
  modifiedSinceLastSubmit?: boolean;
  
  /** Whether form is in its initial, unmodified state */
  pristine?: boolean;
  
  /** Form-level submission error */
  submitError?: any;
  
  /** Field-level submission errors */
  submitErrors?: SubmissionErrors;
  
  /** Whether last submission attempt failed */
  submitFailed?: boolean;
  
  /** Whether last submission attempt succeeded */
  submitSucceeded?: boolean;
  
  /** Whether form is currently being submitted */
  submitting?: boolean;
  
  /** Object indicating which fields have been touched */
  touched?: { [key: string]: boolean };
  
  /** Whether form passes all validation */
  valid?: boolean;
  
  /** Whether form is currently being validated */
  validating?: boolean;
  
  /** Current form values */
  values?: FormValues;
  
  /** Object indicating which fields have been visited */
  visited?: { [key: string]: boolean };
}

Form Subscription Interface

Subscription object for controlling which form state properties trigger updates.

interface FormSubscription {
  active?: boolean;
  dirty?: boolean;
  dirtyFields?: boolean;
  dirtyFieldsSinceLastSubmit?: boolean;
  dirtySinceLastSubmit?: boolean;
  modifiedSinceLastSubmit?: boolean;
  error?: boolean;
  errors?: boolean;
  hasSubmitErrors?: boolean;
  hasValidationErrors?: boolean;
  initialValues?: boolean;
  invalid?: boolean;
  modified?: boolean;
  pristine?: boolean;
  submitError?: boolean;
  submitErrors?: boolean;
  submitFailed?: boolean;
  submitting?: boolean;
  submitSucceeded?: boolean;
  touched?: boolean;
  valid?: boolean;
  validating?: boolean;
  values?: boolean;
  visited?: boolean;
}

Subscription Examples:

// Subscribe only to validation state changes
form.subscribe(
  (state) => {
    if (state.invalid) {
      showErrorMessage('Please fix validation errors');
    }
  },
  { valid: true, invalid: true, errors: true }
);

// Subscribe to submission state
form.subscribe(
  (state) => {
    if (state.submitting) {
      showLoadingSpinner();
    } else if (state.submitSucceeded) {
      showSuccessMessage();
    } else if (state.submitFailed) {
      showErrorMessage('Submission failed');
    }
  },
  { submitting: true, submitSucceeded: true, submitFailed: true }
);

// Subscribe to form dirty state for unsaved changes warning
form.subscribe(
  (state) => {
    if (state.dirty) {
      enableUnsavedChangesWarning();
    } else {
      disableUnsavedChangesWarning();
    }
  },
  { dirty: true, pristine: true }
);

Subscriber Function Types

Type definitions for form state subscriber functions.

type FormSubscriber<
  FormValues = Record<string, any>,
  InitialFormValues extends Partial<FormValues> = Partial<FormValues>
> = (state: FormState<FormValues, InitialFormValues>) => void;

type Unsubscribe = () => void;

Form Subscription Items

List of all available form subscription properties for reference.

const formSubscriptionItems: readonly string[];

The formSubscriptionItems array contains: ["active", "dirty", "dirtyFields", "dirtyFieldsSinceLastSubmit", "dirtySinceLastSubmit", "error", "errors", "hasSubmitErrors", "hasValidationErrors", "initialValues", "invalid", "modified", "modifiedSinceLastSubmit", "pristine", "submitting", "submitError", "submitErrors", "submitFailed", "submitSucceeded", "touched", "valid", "validating", "values", "visited"]

Usage Example:

import { formSubscriptionItems } from "final-form";

// Create a subscription that includes all properties
const fullSubscription = formSubscriptionItems.reduce((acc, item) => {
  acc[item] = true;
  return acc;
}, {});

// Subscribe to all form state changes
form.subscribe(
  (state) => console.log('Full form state:', state),
  fullSubscription
);

Performance Optimization

The subscription system is designed for optimal performance:

// ❌ Bad: Subscribing to all changes causes unnecessary re-renders
form.subscribe(
  (state) => updateUI(state),
  { 
    values: true, 
    errors: true, 
    dirty: true, 
    submitting: true, 
    valid: true,
    // ... many more properties
  }
);

// ✅ Good: Subscribe only to properties you actually use
form.subscribe(
  (state) => {
    if (state.submitting) {
      showSpinner();
    }
  },
  { submitting: true } // Only get notified when submitting changes
);

// ✅ Good: Separate subscriptions for different UI concerns
form.subscribe(
  (state) => updateFormValues(state.values),
  { values: true }
);

form.subscribe(
  (state) => updateValidationErrors(state.errors),
  { errors: true }
);

docs

field-registration.md

form-actions.md

form-creation.md

index.md

state-management.md

utilities.md

validation.md

tile.json