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.