gform-react
Back to Guides

Dispatching Changes

Programmatically update fields - set values, surface errors, or attach your own custom data to form state, at the field or form level.

Most of the time gform-react updates itself as the user types. But sometimes you need to write into the form: prefill values, surface an error from the server, or stash some custom data on a field. That's what dispatchChanges is for. It comes in two flavors - one on a single field, one on the whole form - and both merge into state rather than replacing it.

Field level: state.<formKey>.dispatchChanges

Every field exposes dispatchChanges(changes, options?). Pass a partial field state and gform merges it into that field:

state.email.dispatchChanges({ value: "ada@example.com" });

By default this does not re-run validation - which is exactly what you want when you're surfacing an error yourself (e.g. one the server returned):

// a manually-set error sticks; gform won't validate it away
state.email.dispatchChanges({ error: true, errorText: "Already registered" });

Pass { validate: true } to re-run the field's validators against the new value - use this when a programmatic value change should also update validity:

// set the value AND re-check rules; a `required` field cleared this way will now show its error
state.email.dispatchChanges({ value: "" }, { validate: true });
validate is opt-in

Without { validate: true }, dispatchChanges only merges - it won't touch error/errorText. That's deliberate: it lets you set a manual error (or any state) without gform immediately re-validating it away. Add the option when you want the change reflected in form validity.

Form level: state.dispatchChanges

The form state has its own dispatchChanges that updates any number of fields in one call - keyed by formKey. Handy for seeding several fields at once:

state.dispatchChanges({
  firstName: { value: "Ada" },
  lastName: { value: "Lovelace" },
});

Each field object is merged (not replaced), so the rest of that field's state is preserved. The form-level call doesn't take the { validate: true } option - if you need validation, call the field's own dispatchChanges with it.

Attaching custom data

A field's state isn't limited to the built-in keys. Any extra keys you dispatch are merged onto the field and kept there - gform doesn't strip them. This makes form state a convenient home for transient, field-scoped data:

state.avatar.dispatchChanges({ uploading: true });
state.country.dispatchChanges({ options: ["France", "Japan", "Brazil"] });
state.email.dispatchChanges({ meta: { checkedAt: Date.now() } });

Custom keys show up everywhere the field state is read:

  • inside that field's element render prop - input.uploading, input.options
  • via useFormSelector - useFormSelector((s) => s.fields.avatar.uploading)
  • in a fetch callback - fetch(input, fields) sees fields.country.options
Custom data isn't part of the submitted values

toRawData(), toFormData(), and toURLSearchParams() only read each field's value - they ignore custom keys. Use custom data for UI/transient state (loading flags, fetched option lists, metadata); use value for anything you want in the submitted payload. See Reading Form State.

Updating from a child component

dispatchChanges doesn't require the render prop. Any component inside the form can grab a field with useFormSelector and call its dispatchChanges - no prop drilling:

import { useFormSelector } from "gform-react";
 
function ClearEmailButton() {
  const email = useFormSelector((state) => state.fields.email);
  return (
    <button type="button" onClick={() => email.dispatchChanges({ value: "" }, { validate: true })}>
      Clear email
    </button>
  );
}

See Nested Forms for more on reaching form state from deep in the tree.

Try it live

Loading playground…

Autofill fills both fields in one form-level call. Tag attaches a custom badge key that the render prop shows next to the label (and the <pre> echoes it) - yet it never appears in the submitted data. Clear + validate empties last name and re-runs its rule, so the Required error surfaces.

See Core Concepts for the full state reference and Constraint Validation for how rules run.