circuit

How to listen to Formik onChange event in React?


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