How to listen to Formik onChange event in React?

By Thor Chen

February 5th, 2022

image

I have been asked this question several times recently:

  • I am using Formik in my React project

  • I want to observe (or listen to) the changes of form values

  • But does not provide a prop for onChange callback

How do I do that?

Well, I would like to share two options:

  • #1 Attach callback function on <form> element / component

  • #2 Create a listener / observer component with useFormikContext

Solution 1: Attach callback on <form>

Formik does not provide onChange prop, but <form>(or <Form> if using the wrapper version) does provide it.

So, you can just define a handleOnChange callback function like this:

    const handleOnChange = (event: FormEvent) => {
        console.log("Form::onChange", event);
    };

… and pass it directly to the

:

    <Form **onChange={handleOnChange}**>
        {/* ... */}
    </Form>

The callback is going to receive a synthetic DOM event, and you can access the input element triggering the change via event.target

Solution 2: Create an observer component

Let’s not limit ourselves on the world of DOM, but also have a think from the angle of controlled components — input elements in a Formik form are controlled by states in React, and their states can be accessed and manipulated via FormikContext.

That is, you can create a component to observe (or listen to) the change of values in FormikContext using useEffect hook:

    const FormObserver: React.FC = () => {
      const { values } = useFormikContext();

      useEffect(() => {
        console.log("FormObserver::values", values);
      }, [values]);

      return null;
    };

… and simply put it as a child of :

    <Form>
      {/* ... */}
      **<FormObserver />**
      {/* ... */}
    </Form>

Then you can see the effects runs when form value changes:

Demo / playground

I have created a demo / playground on code sandbox, and you’re welcome to have a try:

Thoughts

While both solutions should work, the mindset is different.

Solution#1: you’re listen to a DOM event, and you will need to access the DOM to get information, which is leaning towards the uncontrolled components pattern.

Solution#2: you’re listen to the state changes without touching DOM, which is leaning towards the controlled components pattern.

I see Formik as a library that emphasis controlled components pattern, so I would recommend Solution#2 to keep mindset consistent while using this library.



Continue Learning