我有一种情况,我必须在一些我无法控制的代码中呈现React控件。它是一个kendo UI网格,我需要在网格单元格中渲染自定义的React组件。
Grid是使用jQuery创建的。它还为父html元素(在表行上)添加了<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>About</title>
<script type="text/javascript">
function val1(val)
{
document.getElementsByTagName("div")[0].setAttribute("data-video", val);
alert(val);
}
</script>
</head>
<body onload="val1('WKV_z36pVAk')">
<h3 style="color:#0066dd">Hello</h3>
<center>
<div data-video="8IYzyTYucKQ"
data-autoplay="0"
data-loop="1"
id="youtube-audio">
</div>
</center>
<button>change</button>
</body>
<script src="https://www.youtube.com/iframe_api"></script>
<script src="https://cdn.rawgit.com/labnol/files/master/yt.js"></script>
</html>
事件侦听器。在我的React组件中,我还有一个click
事件监听器。问题是附加到父级的处理程序首先触发。
下面的代码段(也可用作fiddle)演示了此问题。为了使这个示例尽可能简单,我只使用click
而不是Kendo网格。关键是我们在父html元素上有一个事件处理程序,然后我们用它的div
处理程序将React组件渲染到这个父元素中,并且父元素优先于React。
click
&#13;
class Btn extends React.Component {
constructor(props) {
super(props);
this.click = this.click.bind(this);
}
click() {
alert('Btn');
}
render() {
return (
<span onClick={this.click}>Click me</span>
);
}
};
$(function() {
$('#container').on('click', function() {
alert('JS');
});
ReactDOM.render(
<Btn />,
document.getElementById('btn')
);
});
&#13;
答案 0 :(得分:1)
这很不幸,但是我尽可能地告诉你不能告诉React将其处理程序绑定在树的更深处(它使用document
,然后使用委托)。
要绕过它,你会做一种uncontrolled component(来自Integrating with Other Libraries的链接)并使用ref
来挂钩你的处理程序:
首先我们设置ref:
<span ref={span => this.span = span}>Click me</span>
然后我们使用lifecycle methods添加和删除我们的处理程序:
componentDidMount() {
this.span.addEventListener("click", this.click);
}
componentWillUnmount() {
this.span.removeEventListener("click", this.click);
}
实例:
class Btn extends React.Component {
constructor(props) {
super(props);
this.click = this.click.bind(this);
}
componentDidMount() {
this.span.addEventListener("click", this.click);
}
componentWillUnmount() {
this.span.removeEventListener("click", this.click);
}
click() {
alert('Btn');
}
render() {
return (
<span ref={span => this.span = span}>Click me</span>
);
}
};
$(function() {
$('#container').on('click', function() {
alert('JS');
});
ReactDOM.render(
<Btn />,
document.getElementById('btn')
);
});
<div id="container">
<div id="btn">
</div>
</div>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/react/15.1.0/react-dom.min.js"></script>
(如果您需要支持没有addEventListener
的过时浏览器,请使用jQuery,或者如果您不希望依赖项this answer具有用于挂钩事件的小型跨浏览器功能。需要编写自己的unhook对应物。)
您甚至可以更进一步,只在您安装组件的元素级别挂钩单击处理程序,并根据需要执行您自己的事件委托(或使用jQuery)进行分派。 p>
答案 1 :(得分:0)
这不应该是Kendo Grid for React的本机实现的问题。由于网格正在侦听的事件是使用React而不是jQuery附加的,因此它们遵循React中的冒泡。因此,如果需要,您可以从孩子那里取消它们。 请参阅自定义单元格中包含一些自定义组件的this demo来源。