Javascript React:通过嵌套组件进行事件冒泡
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/32560744/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
React: event bubbling through nested components
提问by kapsi
Let's say I have nested components like this:
假设我有这样的嵌套组件:
<root />
<comp1 />
<comp2 />
<target id={this.props.id}>
<div>click me</div>
I want to make clicking on target run a function on root:
我想让点击目标在 root 上运行一个函数:
//on root component
this.action = function(id){}
Do I need to do manually set a property on every component in the chain, like in the React tutorial example? Jsfiddle
我是否需要在链中的每个组件上手动设置一个属性,就像在 React 教程示例中一样?提琴手
<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>
Or is there some way to bubble the events up like in normal DOM?
或者有什么方法可以像普通 DOM 一样冒泡事件?
采纳答案by Clarkie
You can use the shorthand to pass props through to child components
您可以使用速记将 props 传递给子组件
<Component {...this.props} more="values" />
So in your case:
所以在你的情况下:
<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>
回答by chrismilleruk
React supports Synthetic Events across it's Virtual DOM in both capturing and bubbling phases (as described here: https://facebook.github.io/react/docs/events.html).
React 在捕获和冒泡阶段支持跨虚拟 DOM 的合成事件(如此处所述:https: //facebook.github.io/react/docs/events.html)。
This means that you could put an onClick handler on any DOM element near the root and it should trigger for all Click events on the page:
这意味着您可以在靠近根的任何 DOM 元素上放置一个 onClick 处理程序,并且它应该为页面上的所有 Click 事件触发:
<root>
<div onClick={this.handleAllClickEvents}>
<comp1>
<comp2>
<target>
<div id={this.props.id}>click me</div>
However, since it will fire for allclick events, you would need to disambiguate between them in the click handler (which makes for some pretty ugly code).
但是,由于它将为所有点击事件触发,您需要在点击处理程序中消除它们之间的歧义(这会产生一些非常难看的代码)。
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
}
}
This style of Event Delegation is actually what React does under the hood (https://shripadk.github.io/react/docs/interactivity-and-dynamic-uis.html#under-the-hood-autobinding-and-event-delegation) so you have to ask yourself if that's what you really want to do.
这种事件委托风格实际上是 React 在幕后所做的(https://shripadk.github.io/react/docs/interactivity-and-dynamic-uis.html#under-the-hood-autobinding-and-event-代表团)所以你必须问自己这是否是你真正想做的。
Alternatively you might want to look at something like the Dispatcher pattern in Flux (https://reactjs.org/blog/2014/07/30/flux-actions-and-the-dispatcher.html). It's a little bit more complicated to get going but it's a better solution overall.
或者,您可能想查看 Flux 中的 Dispatcher 模式(https://reactjs.org/blog/2014/07/30/flux-actions-and-the-dispatcher.html)。开始有点复杂,但总体上是一个更好的解决方案。
回答by AlexNikonov
If you want to distinguish which element was clicked at the end, you may use Event object and find there some interesting stuff, such as DOM element type.
如果你想区分最后点击的是哪个元素,你可以使用 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);
...}
And you get buttonor inputdepending on what you've clicked. That's what i looked for for my project.
您会根据点击的内容获得按钮或输入。这就是我为我的项目寻找的东西。
More over you may find a DOM tree in an array representation
Hope it helps
希望能帮助到你