# Formily Lifecycle Events: Complete Guide to Form and Field Hooks

> Explore Formily lifecycle events and master form and field hooks. Utilize over 40 events for initialization, validation, submission, and changes with Formily's powerful effect functions.

- Repository: [Alibaba/formily](https://github.com/alibaba/formily)
- Tags: deep-dive
- Published: 2026-02-24

---

**Formily exposes over 40 lifecycle events through the `LifeCycleTypes` enum in `@formily/core`, allowing you to hook into form initialization, validation, submission, and field-level changes using effect functions like `onFormInit` and `onFieldValueChange`.**

The alibaba/formily library provides a comprehensive reactive form solution with granular lifecycle management. Understanding Formily lifecycle events is essential for building complex forms that require custom validation logic, asynchronous submissions, or dynamic field behavior. These events are defined in the `LifeCycleTypes` enum and exposed through convenient effect hooks that subscribe to form and field state changes.

## Form Lifecycle Events

Form-level lifecycle events cover initialization, mounting, value changes, validation, and submission phases. In [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts), the `LifeCycleTypes` enum defines these events between lines 37-68.

| Event | Description |
|-------|-------------|
| `ON_FORM_INIT` | Form instance has been created. |
| `ON_FORM_MOUNT` | Form has been mounted (e.g., after `form.mount()` or component mount). |
| `ON_FORM_UNMOUNT` | Form is being unmounted. |
| `ON_FORM_INPUT_CHANGE` | Any input value in the form changed (raw input before normalization). |
| `ON_FORM_VALUES_CHANGE` | Normalized form values changed. |
| `ON_FORM_INITIAL_VALUES_CHANGE` | Initial values of the form changed (usually via `form.setInitialValues`). |
| `ON_FORM_SUBMIT` | Form submission started (no validation yet). |
| `ON_FORM_RESET` | Form has been reset to its initial state. |
| `ON_FORM_SUBMIT_START` | Submission lifecycle start (after validation). |
| `ON_FORM_SUBMITTING` | While the submit async process is running. |
| `ON_FORM_SUBMIT_END` | Submission finished (regardless of success/failure). |
| `ON_FORM_SUBMIT_VALIDATE_START` | Validation that runs before submit begins. |
| `ON_FORM_SUBMIT_VALIDATE_SUCCESS` | Validation succeeded before submit. |
| `ON_FORM_SUBMIT_VALIDATE_FAILED` | Validation failed before submit. |
| `ON_FORM_SUBMIT_VALIDATE_END` | End of the pre‑submit validation phase. |
| `ON_FORM_SUBMIT_SUCCESS` | Submit async handler resolved successfully. |
| `ON_FORM_SUBMIT_FAILED` | Submit async handler rejected. |
| `ON_FORM_VALIDATE_START` | General validation start (e.g., `form.validate()`). |
| `ON_FORM_VALIDATING` | Validation is in progress. |
| `ON_FORM_VALIDATE_SUCCESS` | Validation succeeded. |
| `ON_FORM_VALIDATE_FAILED` | Validation failed. |
| `ON_FORM_VALIDATE_END` | Validation cycle finished. |
| `ON_FORM_GRAPH_CHANGE` | Internal form graph (dependency tree) changed. |
| `ON_FORM_LOADING` | Form enters a loading state. |

## Field Lifecycle Events

Field-level events allow you to react to individual input changes, validation states, and UI mounting operations. These constants are defined in `LifeCycleTypes` at lines 71-98 of [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts).

| Event | Description |
|-------|-------------|
| `ON_FIELD_INIT` | Field instance has been created. |
| `ON_FIELD_INPUT_VALUE_CHANGE` | Raw input value of the field changed. |
| `ON_FIELD_VALUE_CHANGE` | Normalized field value changed. |
| `ON_FIELD_INITIAL_VALUE_CHANGE` | Field's initial value changed. |
| `ON_FIELD_SUBMIT` | Field participates in form submit (e.g., value collected). |
| `ON_FIELD_SUBMIT_START` | Submit phase start for the field. |
| `ON_FIELD_SUBMITTING` | Field is being submitted asynchronously. |
| `ON_FIELD_SUBMIT_END` | Submit phase end for the field. |
| `ON_FIELD_SUBMIT_VALIDATE_START` | Validation before submit for the field. |
| `ON_FIELD_SUBMIT_VALIDATE_SUCCESS` | Field validation succeeded before submit. |
| `ON_FIELD_SUBMIT_VALIDATE_FAILED` | Field validation failed before submit. |
| `ON_FIELD_SUBMIT_VALIDATE_END` | End of field‑pre‑submit validation. |
| `ON_FIELD_SUBMIT_SUCCESS` | Field submit succeeded. |
| `ON_FIELD_SUBMIT_FAILED` | Field submit failed. |
| `ON_FIELD_VALIDATE_START` | Field validation start (independent of submit). |
| `ON_FIELD_VALIDATING` | Field is currently validating. |
| `ON_FIELD_VALIDATE_SUCCESS` | Field validation succeeded. |
| `ON_FIELD_VALIDATE_FAILED` | Field validation failed. |
| `ON_FIELD_VALIDATE_END` | Field validation cycle finished. |
| `ON_FIELD_LOADING` | Field enters a loading state. |
| `ON_FIELD_RESET` | Field has been reset to its initial value. |
| `ON_FIELD_MOUNT` | Field has been mounted in the UI. |
| `ON_FIELD_UNMOUNT` | Field has been removed from the UI. |

## Implementing Lifecycle Hooks

Instead of manually subscribing to `LifeCycleTypes` enum values, Formily provides ergonomic helper functions exported from [`packages/core/src/effects/onFormEffects.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/effects/onFormEffects.ts). These wrappers handle the subscription logic internally.

### Form-Level Hooks

```typescript
import {
  onFormInit,
  onFormValuesChange,
  onFormSubmitStart,
  onFormSubmitEnd,
  onFormValidateFailed,
} from '@formily/core';

// Log when a form is created
onFormInit((form) => {
  console.log('Form created →', form);
});

// React to normalized value changes
onFormValuesChange((form) => {
  console.log('Form values changed →', form.values);
});

// Submit lifecycle monitoring
onFormSubmitStart((form) => {
  console.log('Submitting…');
});

onFormSubmitEnd((form, result) => {
  console.log('Submit finished, result:', result);
});

onFormValidateFailed((form, errors) => {
  console.error('Form validation failed:', errors);
});

```

### Field-Level Hooks

```typescript
import {
  onFieldInit,
  onFieldValueChange,
  onFieldValidateStart,
  onFieldValidateFailed,
  onFieldSubmitSuccess,
} from '@formily/core';

// Target specific fields by path
onFieldInit((field) => {
  if (field.path?.toString() === 'username') {
    console.log('Username field initialized');
  }
});

// Monitor value changes
onFieldValueChange((field) => {
  if (field.path?.toString() === 'age') {
    console.log('Age changed to', field.value);
  }
});

// Validation lifecycle
onFieldValidateStart((field) => {
  console.log(`Validating ${field.path}`);
});

onFieldValidateFailed((field, errors) => {
  console.warn(`Field ${field.path} validation errors:`, errors);
});

// Submit success for specific field
onFieldSubmitSuccess((field, result) => {
  console.log(`Field ${field.path} submitted successfully`, result);
});

```

## Core Implementation Architecture

Lifecycle events are dispatched through the `notify` method implemented in the core models. When you register a hook, it internally subscribes to notifications fired by these methods.

The `Form` class implements `Form.notify` in [`packages/core/src/models/Form.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Form.ts) (lines 304-330). This method broadcasts events to all registered listeners for form-level lifecycle types.

Fields use `BaseField.notify` defined in [`packages/core/src/models/BaseField.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/BaseField.ts) (lines 305-317). The concrete `Field` class in [`packages/core/src/models/Field.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Field.ts) inherits this behavior to trigger field-specific events.

When `form.notify(LifeCycleTypes.ON_FORM_VALUES_CHANGE)` executes during a state update, all callbacks registered via `onFormValuesChange` receive the form instance as an argument. Similarly, `field.notify(LifeCycleTypes.ON_FIELD_VALUE_CHANGE)` invokes listeners registered through `onFieldValueChange`.

## Summary

- **Formily lifecycle events** are defined as constants in the `LifeCycleTypes` enum located in [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts)
- **Form events** cover initialization (`ON_FORM_INIT`), mounting (`ON_FORM_MOUNT`), submission phases (`ON_FORM_SUBMIT_START`, `ON_FORM_SUBMIT_END`), and validation cycles (`ON_FORM_VALIDATE_START`, `ON_FORM_VALIDATE_SUCCESS`, `ON_FORM_VALIDATE_FAILED`)
- **Field events** provide granular control over individual inputs (`ON_FIELD_INPUT_VALUE_CHANGE`), normalized values (`ON_FIELD_VALUE_CHANGE`), and field-specific validation states
- **Effect helpers** like `onFormInit` and `onFieldValueChange` from `@formily/core` provide type-safe subscriptions without referencing raw enum values
- **Event dispatching** occurs through `Form.notify()` and `BaseField.notify()` methods in their respective model classes, triggering all registered callbacks asynchronously

## Frequently Asked Questions

### What is the difference between ON_FORM_INPUT_CHANGE and ON_FORM_VALUES_CHANGE?

**`ON_FORM_INPUT_CHANGE`** fires when raw input values change before any normalization or formatting occurs, while **`ON_FORM_VALUES_CHANGE`** fires after the values have been processed and normalized. Use the former to intercept user input immediately, and the latter to react to final data state changes.

### How do I listen to lifecycle events for a specific field only?

Filter by the `path` property inside your callback function. Both form and field hooks receive the target instance as an argument, allowing you to check `field.path.toString()` or `field.path.toArr()` before executing logic, as shown in the field-level examples targeting `username` and `age` fields.

### What is the execution order of submission lifecycle events?

The sequence follows: `ON_FORM_SUBMIT` (initial trigger) → `ON_FORM_SUBMIT_VALIDATE_START` (validation begins) → `ON_FORM_SUBMIT_VALIDATE_SUCCESS` or `ON_FORM_SUBMIT_VALIDATE_FAILED` → `ON_FORM_SUBMIT_START` (post-validation) → `ON_FORM_SUBMITTING` (async operation) → `ON_FORM_SUBMIT_SUCCESS` or `ON_FORM_SUBMIT_FAILED` → `ON_FORM_SUBMIT_END` (final cleanup).

### Where are lifecycle events implemented in the Formily source code?

Event constants reside in [`packages/core/src/types.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/types.ts) (the `LifeCycleTypes` enum). The notification mechanism is implemented in [`packages/core/src/models/Form.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/Form.ts) for forms and [`packages/core/src/models/BaseField.ts`](https://github.com/alibaba/formily/blob/main/packages/core/src/models/BaseField.ts) for fields, specifically in the `notify` methods that iterate through registered listeners when state changes occur.