reactjsreactjs-testutils

Why React event handler is not called on dispatchEvent?


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?


Solution

  • 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