title: Changing the value of a react input component with JS doesn't fire the inputs onChange event
body: <p>I have a range input that has a few things happening <code>onChange</code>.  This works as I'd expect with manual click/drag usage.  However, when I try to change the value with JavaScript, my <code>onChange</code> event doesn't seem to fire.</p>
  
  <p><strong>Here is my code:</strong> </p>
  
  <pre><code>const App = () =&gt; {
    const [currentValue, setCurrentValue] = useState(0);
  
    const setRangeValue = () =&gt; {
      const range = document.querySelector("input");
  
      range.value = 50;
      range.dispatchEvent(new Event("change", { bubbles: true }));
    };
  
    return (
      &lt;div className="App"&gt;
        &lt;h1&gt;Current Value: {currentValue}&lt;/h1&gt;
  
        &lt;input
          type="range"
          min={0}
          max={100}
          step={10}
          onChange={e =&gt; {
            console.log("Change!");
            setCurrentValue(+e.target.value);
          }}
          defaultValue={0}
        /&gt;
  
        &lt;button onClick={setRangeValue}&gt;Set current value to 50&lt;/button&gt;
      &lt;/div&gt;
    );
  };
  </code></pre>
  
  <p><strong>And here it is (not) working in CodeSandbox:</strong>
  <a href="https://codesandbox.io/s/divine-resonance-rps1n" rel="nofollow noreferrer">https://codesandbox.io/s/divine-resonance-rps1n</a></p>
  
  <p><strong>NOTE:</strong></p>
  
  <p>Just to clarify.  My actual issue comes from testing my component with jest/react testing library.  The button demo is just a nice way to visualize the problem without getting into the weeds of having to duplicate all of my test stuff too.</p>
  
  <pre><code>    const getMessage = (value, message) =&gt; {
          const slider = getByRole('slider');
          fireEvent.change(slider, { target: { value } });
          slider.dispatchEvent(new Event('change', { bubbles: true }));
          return getByText(message).innerHTML;
      };
  </code></pre>
  
  <p>When the fireEvent changes the value, it doesn't run the <code>onChange</code> events attached to the input.  Which means that <code>getByText(message).innerHTML</code> is incorrect, as that will only update when a set hook gets called <code>onChange</code>.  (All of this works when manually clicking/dragging the input slider, I just can't "test" it)</p>
  
  <p>Any help would be great!</p>