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)
但是这些都不会触发onChange
React 组件中的处理程序,因此状态不会更新。
我的问题:如何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)
为后代回答我自己的问题。
事实证明,这个问题是双重的。但首先,一些背景:
反应事件
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
归档时间: |
|
查看次数: |
2832 次 |
最近记录: |