Why React event handler is not called on dispatchEvent?
One way to do it without ReactTestUtils.Simulate
:
var script = document.createElement('script');script.type = 'text/javascript';script.src = 'https://unpkg.com/react-trigger-change/dist/react-trigger-change.js';document.head.appendChild(script);input.value = value;reactTriggerChange(input);
Look at the source of react-trigger-change to just cherry-pick what's needed. Example snippet:
if (nodeName === 'select' || (nodeName === 'input' && type === 'file')) { // IE9-IE11, non-IE // Dispatch change. event = document.createEvent('HTMLEvents'); event.initEvent('change', true, false); node.dispatchEvent(event); }
React uses its own events system with SyntheticEvents
(prevents browser incompatabilities and gives react more control of events).
Using TestUtils
correctly creates such a event which will trigger your onChange
listener.
The dispatchEvent
function on the other hand will create a "native" browser event. But the event handler you have is managed by react and therefore only reacts (badumts) to reacts SyntheticEvents
.
You can read up on react events here: https://facebook.github.io/react/docs/events.html
I created a small version of the https://github.com/vitalyq/react-trigger-change only for the input element.
No external dependencies, copypaste and it will work.
Works for React 16.9, checked with Safari (14), Chrome (87), and Firefox (72).
const triggerInputChange = (node: HTMLInputElement, inputValue: string) => { const descriptor = Object.getOwnPropertyDescriptor(node, 'value'); node.value = `${inputValue}#`; if (descriptor && descriptor.configurable) { delete node.value; } node.value = inputValue; const e = document.createEvent('HTMLEvents'); e.initEvent('change', true, false); node.dispatchEvent(e); if (descriptor) { Object.defineProperty(node, 'value', descriptor); }};