简体   繁体   English

为什么jQuery中的'change'事件不会在ReactJS中触发onChange?

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

I am writing tests for ReactJS components in karma + PhatomJS. 我正在为karma + PhatomJS编写ReactJS组件的测试。 I am rendering the component and using jQuery as a shortcut to target dom elements and simulate user actions. 我正在渲染组件并使用jQuery作为目标dom元素和模拟用户操作的快捷方式。 Clicking, text input, etc works fine. 单击,文本输入等工作正常。 However, the selection in a select doesn't seem to execute the component's onChange event. 但是,select中的选择似乎不执行组件的onChange事件。 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. 但是,没有jQuery,它似乎工作得很好。 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 ! ReactJS中的回调被触发了

I cannot spot any difference. 我无法发现任何差异。 I thought that the code above is practically the same what jQuery does with .val('B').change(). 我认为上面的代码实际上与jQuery对.val('B').change()的作用相同。 Perhaps a jQuery ninja can give me a hint on this one? 或许一个jQuery忍者可以给我一个暗示吗?

It doesn't work with jQuery change() because that doesn't trigger a "real" change event. 它不适用于jQuery change()因为它不会触发“真正的” change事件。 It's a shortcut for .trigger('change') which says 它是.trigger('change')的捷径

A call to .trigger() executes the handlers in the same order they would be if the event were triggered naturally by the user 对.trigger()的调用以与用户自然触发事件时相同的顺序执行处理程序

and

Although .trigger() simulates an event activation, complete with a synthesized event object, it does not perfectly replicate a naturally-occurring event. 虽然.trigger()模拟事件激活,但是使用合成的事件对象,它并不能完美地复制自然发生的事件。

I believe this was done in order to help support very old versions of IE that had different handling of events. 我相信这样做是为了帮助支持具有不同事件处理的非常旧版本的IE。

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. 只是本机地触发事件会使您的测试与您的实现选择相结合。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM