Roman Semko Roman Semko - 1 year ago 158
jQuery Question

Why doesn't the 'change' event in jQuery fire onChange in ReactJS?

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
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>

ReactDOM.render(<SelectComponent />, document.createElement('div'))

// Pragmatically change the selection

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?

Answer Source

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


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 any rate, since that's what you wanted to know.