I am writing tests for ReactJS components in karma + PhatomJS. I am rendering the component and using jQuery as a shortcut to target dom elements and simulate user actions. Clicking, text input, etc works fine. However, the selection in a select doesn't seem to execute the component's onChange event. Here's the code:
import React from 'react'
import ReactDOM from 'react-dom'
import $ from 'jquery'
class SelectComponent extends React.Component {
handleChange (event) {
// This is NEVER fired
doSomething()
}
render () {
return (
<select id='Fruits' onChange={this.handleChange.bind(this)}>
<option value='A'>Apple</option>
<option value='B'>Banana</option>
<option value='C'>Cranberry</option>
</select>
)
}
}
ReactDOM.render(<SelectComponent />, document.createElement('div'))
// Pragmatically change the selection
$('#Fruits').val('B').change()
However, without jQuery, it seems to work just fine. When I change the last line to:
const element = document.getElementById('Fruits')
element.value = value
element.dispatchEvent(new Event('change', { bubbles: true }))
the callback in ReactJS gets fired!
I cannot spot any difference. I thought that the code above is practically the same what jQuery does with .val('B').change(). Perhaps a jQuery ninja can give me a hint on this one?
It doesn't work with jQuery change()
because that doesn't trigger a "real" change
event. It's a shortcut for .trigger('change') which says
A call to .trigger() executes the handlers in the same order they would be if the event were triggered naturally by the user
and
Although .trigger() simulates an event activation, complete with a synthesized event object, it does not perfectly replicate a naturally-occurring event.
I believe this was done in order to help support very old versions of IE that had different handling of events.
That's the why of it at any rate, since that's what you wanted to know. Just firing the event natively makes your tests less coupled with your implementation choices.
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