Business
Jobs
  • About Us
  • Solutions
    • Job Postings
      Post your job and receive qualified candidates in 48h.
    • Candidate Assessments
      500+ technical and psychological tests, plus anti-fraud.
    • Headhunting
      Tailor-made executive search from start to finish.
    • Payroll + EOR
      Payroll dispersal and EOR across 15+ LATAM countries.
  • Pricing
  • Jobs

0

195
Views
Why does the onChange event handler on <form> pick upp dispatched events from <select>, but not <input>?

I'm building an application in React with many complex forms, and I'm trying to use the onChange event handler on the <form> element.

<form onChange={handleChange}>
  <input name="input1" />
  <input name="input2" />
  ...
</form>

This works great when listening to changes of regular HTML-inputs, but when building a <CustomInput>, I have trouble triggering the onChange on the <form>.

I have created a "hidden" <input> and manually dispatches an Event("change"), but it was not picked up by the onChange on the <form>, however, it does work for the <select> input.

import { useRef } from "react";

function App() {
  const inpRef = useRef();
  const selRef = useRef();

  function onChange(e) {
    console.log(e.target.name); // Only "select" is logged
  }

  function dispatchChange() {
    inpRef.current.dispatchEvent(new Event("change", { bubbles: true }));
    selRef.current.dispatchEvent(new Event("change", { bubbles: true }));
  }
  return (
    <>
      <form onChange={onChange}>
        <input ref={inpRef} name="input" />
        <select ref={selRef} name="select" />
      </form>
      <button onClick={dispatchChange}>Trigger change</button>
    </>
  );
}

export default App;

Why does the "change" event for <select> trigger onChange, but not <input>?

about 4 years ago · Juan Pablo Isaza
1 answers
Answer question

0

This problem is happening because the "change event" of the input is quiet special. It is managed by "ChangeEventPlugin".

One of the restrictions of this plugin is that the "change" event only will be dispatched if the input value actually changes.

To solve the problem, you have to add this in your code:

useEffect(() => {
    inpRef.current._valueTracker.getValue = () => {
      return 'fake value'
    }
  }, []);

And import "useEffect", of course.

import { useEffect, useRef } from 'react';

So, at the end, the full code will be:

import { useEffect, useRef } from 'react';

function App() {
  const inpRef = useRef();
  const selRef = useRef();

  function onChange(e) {
    console.log(e.target.name); // Only "select" is logged
  }

  function dispatchChange() {
    inpRef.current.dispatchEvent(new Event("change", { bubbles: true }));
    selRef.current.dispatchEvent(new Event("change", { bubbles: true }));
  }

  useEffect(() => {
    inpRef.current._valueTracker.getValue = () => {
      return 'fake value'
    }
  }, []);

  return (
    <>
      <form onChange={onChange}>
        <input ref={inpRef} name="input" />
        <select ref={selRef} name="select" />
      </form>
      <button onClick={dispatchChange}>Trigger change</button>
    </>
  );
}

export default App;

I hope I've helped you. Have a nice day and happy new year!

about 4 years ago · Juan Pablo Isaza Report
Answer question
Find remote jobs

Discover the new way to find a job!

Top jobs
Top job categories
Business
Post vacancy Pricing Sales
Legal
Terms and conditions Privacy policy
© 2026 PeakU Inc. All Rights Reserved.
Andres GPT
Show me some job opportunities
There's an error!