Skip to main content


This hook can be used for two purposes:

  • Isolating re-rendering: It helps us to isolate re-rendering at the component level for performance optimization (see related article). The API design similar to the use method of the useForm that maintain a consistent DX for us. See the Isolating Re-rendering to learn more.
  • On state change event: To listen for changes to properties in the form state without triggering re-renders. See the On State Change Event to learn more.
// Isolating re-rendering modeconst props = useFormState(path, config);
// On state change event modeuseFormState(path, callback, formId);


string | string[] | Record<string, string>

The path of the property we want to access from the form state. We can construct the return values as follows.

  • Every time an accessed value changed that will trigger re-renders. Thus, there're some guidelines for us to use the form state.
  • You can access the form's values without the values. prefix, ya! it's a shortcut for for your convenience.
// Getting a valueconst foo = useFormState("");
// Shortcut for getting a valueconst foo = useFormState("foo");
// Array pickconst [foo, bar] = useFormState(["", ""]);
// Object pickconst { foo, bar } = useFormState({ foo: "", bar: "" });


An object with the following options:



The corresponding ID of the useForm hook. We only need it when using multiple form hooks at the same time.



The alternative default values for this hook to return when we didn't provide them via the defaultValues option of the useForm. Two common use cases of this option are as follows:

  • Setting a default value for a field via the defaultValue attribute.
  • Setting a default value for a field via the useControlled's defaultValue option.



Enable/disable the feature of filtering untouched errors, which can help the user focus on typing without being annoyed by the error message. Default is false.

// Current state: { errors: { foo: "Required" }, touched: {} }// Returns { foo: "Required" }const errors = useFormState("errors");
// Current state: { errors: { foo: "Required" }, touched: {} }// Returns {}const errors = useFormState("errors", { errorWithTouched: true );
// Current state: { errors: { foo: "Required" }, touched: { foo: true } }// Returns { foo: "Required" }const errors = useFormState("errors", { errorWithTouched: true );


(props: any) => void

It's called on any of the subscribed properties in the form state change. It takes the properties as the parameter.



An optional parameter that works the same as the config.formId.


The example demonstrates the basic usage of this hook.

import { useFormState } from "react-cool-form";
// To isolate re-rendering at the component levelconst IsolatedComponent = () => {  const foo = useFormState("foo");
  return <div>{foo}</div>;};
// To listen for the changes of a field valueuseFormState("foo", (foo) => console.log(foo));