我们说我有这样的嵌套组件:
<root />
<comp1 />
<comp2 />
<target id={this.props.id}>
<div>click me</div>
我想点击目标在root上运行一个函数:
//on root component
this.action = function(id){}
我是否需要在链中的每个组件上手动设置属性,就像在React教程示例中一样? Jsfiddle
<root />
<comp1 clickHandler={this.action}/>
<comp2 clickHandler={this.clickHandler}/>
<target id={this.props.id} clickHandler={this.clickHandler} />
<div onClick={this.props.clickHandler.bind(this, this.props.id)}>click me</div>
或者是否有某种方法可以像普通的DOM那样冒泡事件?
答案 0 :(得分:31)
React在捕获和冒泡阶段支持虚拟DOM的合成事件(如下所述:while)。
这意味着您可以在根目录附近的任何DOM元素上放置onClick处理程序,它应该触发页面上的所有Click事件:
<root>
<div onClick={this.handleAllClickEvents}>
<comp1>
<comp2>
<target>
<div id={this.props.id}>click me</div>
但是,由于它将触发所有点击事件,因此您需要在点击处理程序中消除它们之间的歧义(这会产生一些相当丑陋的代码)。
function handleAllClickEvents(event) {
var target = event.relatedTarget;
var targetId = target.id;
switch(targetId) {
case 'myBtn1':
// handle myBtn1 click event
case 'myBtn2':
// handle myBtn2 click event
}
}
这种风格的事件代表团实际上是React所做的事情(https://facebook.github.io/react/docs/events.html)所以你必须问问自己这是不是你真正想做的事情。
或者,您可能希望查看Flux中的Dispatcher模式(https://shripadk.github.io/react/docs/interactivity-and-dynamic-uis.html#under-the-hood-autobinding-and-event-delegation)。这是一个更复杂的开始,但它是一个更好的解决方案。
答案 1 :(得分:5)
您可以使用速记将道具传递给子组件
<Component {...this.props} more="values" />
所以在你的情况下:
<root />
<comp1 clickHandler={this.action}/>
<comp2 {...this.props} />
<target {...this.props} id={this.props.id} />
<div onClick={this.props.clickHandler.bind(this, this.props.id)}>click me</div>
答案 2 :(得分:0)
如果要区分最后单击了哪个元素,则可以使用Event对象,并在其中找到一些有趣的东西,例如DOM元素类型。
<AnElement>
<button onClick={e => this.eventHandler(e)}>Click me</button>
<input type="text" onClick={e => this.eventHandler(e)}>Click me</input>
eventHandler = (e) => {
console.log(e, e.nativeEvent.toElement.nodeName);
...}
然后您会根据所单击的内容获得按钮或输入。 这就是我为我的项目寻找的东西。
希望有帮助