Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why React event handler is not called on dispatchEvent?

Tags:

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?

like image 737
Misha Moroshko Avatar asked Aug 21 '16 13:08

Misha Moroshko


People also ask

Why this is undefined in event handler?

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.

How do you dispatch custom events in React?

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.

How do you trigger an event in React?

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.

How do you call a function on button click in react JS?

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.


1 Answers

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);   } 
  • https://github.com/vitalyq/react-trigger-change
  • https://github.com/facebook/react/issues/3249#issuecomment-292919084
like image 187
rofrol Avatar answered Oct 14 '22 09:10

rofrol