如何使用纯 DOM Javascript 以编程方式触发 React 组件中的 <select> onChange?

mer*_*ial 3 javascript dom reactjs

我有一个简单的 React 组件:

state = {
  value: '',
};

render() {
  return <select onChange={this.handleChange} value={this.state.value}>
    <option value="">--</option>
    <option value="1">One</option>
  </select>;
}

handleChange = (e) => {
  this.setState({
    value: e.target.value,
  });
  console.log('Handling Change!!')
};
Run Code Online (Sandbox Code Playgroud)

我希望能够通过普通的 javascript 或在本例中通过 jQuery 以编程方式触发事件处理程序

$select = $('select');
$select.val('1');
// then
$select.trigger('change');
// or
$select.trigger('input');
Run Code Online (Sandbox Code Playgroud)

但是这些都不会触发onChangeReact 组件中的处理程序,因此状态不会更新。

我的问题:如何onChange使用 DOM 和 Javascript触发处理程序?

[编辑]

为了进一步澄清,我正在像这样安装 React 组件:

el = document.createElement('div')
ReactDOM.render(MySelect, el)

$select = $(el).find('select');
$select.val('1');
// then
$select.trigger('change');
// or
$select.trigger('input');
Run Code Online (Sandbox Code Playgroud)

mer*_*ial 7

为后代回答我自己的问题。

事实证明,这个问题是双重的。但首先,一些背景:

反应事件

React 事件系统通过委托给根节点来监听原生 DOM 事件。即它不使用 将侦听器附加到每个元素onChange,而只是在根文档上侦听通过 DOM冒泡的事件

对于那些熟悉 jQuery 委托事件的人来说,这类似于

$(document).on('change', '.my-select', callback)
Run Code Online (Sandbox Code Playgroud)

jQuery 事件

其次,jQuery 本身在某种程度上“覆盖”了 DOM 本地事件冒泡,它有自己的系统,这就是您可以抛出自定义事件的方式。

解决方案...

如前所述,我有 2 个问题,因此有 2 个解决方案:

第一的

由于 jQuery 使用它自己的事件系统,事件被触发

$(select).trigger('change')
Run Code Online (Sandbox Code Playgroud)

不会到达 React 的根事件侦听器。所以我们用......

select.dispatchEvent(new Event('change', {bubbles, true}));
Run Code Online (Sandbox Code Playgroud)

……但这还不够。

第二

DOM 事件从元素冒泡到文档根。但请注意,我从未将我的元素附加到文档中!!change事件冒泡达...无处!同样,它永远不会到达在文档上注册的 React 事件侦听器。

如果我像这样将我的元素添加到 DOM:

el = document.createElement('div')
ReactDOM.render(MySelect, el)
document.body.appendChild(el) // <-- attach to DOM
Run Code Online (Sandbox Code Playgroud)

现在事件到达 React 事件侦听器,并且onChange我的组件中的原始处理程序被触发。

我希望这可以帮助遇到类似问题的任何人。

附:我发现这个 reactjs 文件中的文档有助于理解 React 事件系统:https : //github.com/facebook/react/blob/master/packages/react-dom/src/events/ReactBrowserEventEmitter.js