Consider the following input element in a React component:
<input onChange={() => console.log('onChange')} ... />
While testing the React component, I'm emulating user changing the input value:
input.value = newValue; TestUtils.Simulate.change(input);
This causes 'onChange'
to be logged, as expected.
However, when the 'change'
event is dispatched directly (I'm using jsdom):
input.value = newValue; input.dispatchEvent(new Event('change'));
the onChange
handler is not called.
Why?
My motivation to use dispatchEvent
rather than TestUtils.Simulate
is because TestUtils.Simulate
doesn't support event bubbling and my component's behavior relies on that. I wonder whether there is a way to test events without TestUtils.Simulate
?
The attribute onClick just stores a reference to that function. Whenever a user clicks on the button, that referenced function is called on the global object. So the keyword this is set to undefined in the strict mode.
dispatchEvent(event); If we wanted to add a bit more data to our custom event, we could do so through the CustomEvent interface using the detail property: //First, we initialize our event const event = new CustomEvent('onDialogClose', {detail: "Main Dialog"}); // Next, we dispatch the event.
To add the click event in React using plain JavaScript, you need to use addEventListener() to assign the click event to an element. Create one <button> element as ref props so that it can be accessed to trigger the click event.
The React onClick event handler enables you to call a function and trigger an action when a user clicks an element, such as a button, in your app. Event names are written in camelCase, so the onclick event is written as onClick in a React app. In addition, React event handlers appear inside curly braces.
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); }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With