I’m creating my custom React component with some extra features. I would like to keep it as close to the default browser behavior as possible. Whenever I change something in the form’s input I would like the change event to bubble up to the form. Unfortunately, I can’t make it work.
I’ve read that the "change" event is apparently some special even in React’s synthetic event system. None of the proposed solutions worked for me as they were for older React versions.
To simplify my problem I created this demo and what I would like to do is to trigger the form.onChange from within input’s onPointerDown or whatever other event handler. Of course I can’t call the form.onChange directly as I’m not in the control of this part of the code. Everything should be done through events bubbling. Is it even possible in React? I’ve tested it in some of the popular UI libraries and so far none of them does that for non-native select components.
export function Demo() {
return (
<form
onChange={(event) => {
const form = event.currentTarget;
const formData = new FormData(form);
console.log(JSON.stringify(Array.from(formData)));
}}
>
<input
name="name"
onPointerDown={(event) => {
const changeEvent = new Event("change", { bubbles: true });
event.currentTarget.dispatchEvent(changeEvent);
}}
/>
</form>
);
}
2
Answers
You can’t directly call onChange event of the form by dispatching it from an input.
The onChange event of the form will trigger on any form’s inputs changes.
React optimizes event handling by tracking the value changes of form elements. Without actually changing the input’s value, React might not recognize the event as a meaningful change, even if the event is dispatched.
I think this is reasonable, because what’s the point of calling onChange on a form (from input’s onPointerDown in your case) if the values of its inputs haven’t changed?
Solution 1 : Add events to form on need basis.
The following code shows the same.
The coding highlights:
a. A ref object is used to get access to the form object.
b. The handler addEventToForm will add events to the form object.
c. The handler listenerForAllFormEvents is the same handler will listen to all events added.
App.js
Test run