dmw*_*268 85 onclick event-propagation reactjs
这是一个基本组件.无论是<ul>和<li>拥有的onClick功能.我只想点击on on <li>,而不是<ul>.我怎样才能做到这一点?
我打得四处e.preventDefault(),e.stopPropagation(),但没有成功.
class List extends React.Component {
constructor(props) {
super(props);
}
handleClick() {
// do something
}
render() {
return (
<ul
onClick={(e) => {
console.log('parent');
this.handleClick();
}}
>
<li
onClick={(e) => {
console.log('child');
// prevent default? prevent propagation?
this.handleClick();
}}
>
</li>
</ul>
)
}
}
// => parent
// => child
Run Code Online (Sandbox Code Playgroud)
Wil*_*one 115
我遇到过同样的问题.我发现stopPropagation 确实有效.我将列表项拆分为一个单独的组件,如下所示:
class List extends React.Component {
handleClick = e => {
// do something
}
render() {
return (
<ul onClick={this.handleClick}>
<ListItem onClick={this.handleClick}>Item</ListItem>
</ul>
)
}
}
class ListItem extends React.Component {
handleClick = e => {
e.stopPropagation(); // <------ Here is the magic
this.props.onClick();
}
render() {
return (
<li onClick={this.handleClick}>
{this.props.children}
</li>
)
}
}
Run Code Online (Sandbox Code Playgroud)
Pri*_*han 48
React使用事件委托在文档上使用单个事件侦听器来处理冒泡的事件,例如本例中的"click",这意味着无法停止传播; 当你在React中与它交互时,真实事件已经传播了.由于React在内部处理合成事件的传播,因此可以对React的合成事件进行stopPropagation.
stopPropagation: function(e){
e.stopPropagation();
e.nativeEvent.stopImmediatePropagation();
}
Run Code Online (Sandbox Code Playgroud)
Tob*_*ist 44
事件如何传播有两个阶段。这些被称为“捕获”和“冒泡”。
| | / \
---------------| |----------------- ---------------| |-----------------
| element1 | | | | element1 | | |
| -----------| |----------- | | -----------| |----------- |
| |element2 \ / | | | |element2 | | | |
| ------------------------- | | ------------------------- |
| Event CAPTURING | | Event BUBBLING |
----------------------------------- -----------------------------------
Run Code Online (Sandbox Code Playgroud)
捕获阶段首先发生,然后是冒泡阶段。当您使用常规 DOM api 注册事件时,默认情况下事件将成为冒泡阶段的一部分,但这可以在创建事件时指定
| | / \
---------------| |----------------- ---------------| |-----------------
| element1 | | | | element1 | | |
| -----------| |----------- | | -----------| |----------- |
| |element2 \ / | | | |element2 | | | |
| ------------------------- | | ------------------------- |
| Event CAPTURING | | Event BUBBLING |
----------------------------------- -----------------------------------
Run Code Online (Sandbox Code Playgroud)
在 React 中,冒泡事件也是你默认使用的。
// handleClick is a BUBBLING (synthetic) event
<button onClick={handleClick}></button>
// handleClick is a CAPTURING (synthetic) event
<button onClickCapture={handleClick}></button>
Run Code Online (Sandbox Code Playgroud)
// CAPTURING event
button.addEventListener('click', handleClick, true)
// BUBBLING events
button.addEventListener('click', handleClick, false)
button.addEventListener('click', handleClick)
Run Code Online (Sandbox Code Playgroud)
// handleClick is a BUBBLING (synthetic) event
<button onClick={handleClick}></button>
// handleClick is a CAPTURING (synthetic) event
<button onClickCapture={handleClick}></button>
Run Code Online (Sandbox Code Playgroud)
如果在所有事件中调用 e.preventDefault() ,则可以检查事件是否已被处理,并防止再次处理它:
function handleClick(e) {
// This will prevent any synthetic events from firing after this one
e.stopPropagation()
}
Run Code Online (Sandbox Code Playgroud)
合成事件和原生事件的区别参见 React 文档:https : //reactjs.org/docs/events.html
ril*_*lar 17
这是防止单击事件前进到下一个组件然后调用 yourFunction 的简单方法。
<Button onClick={(e)=> {e.stopPropagation(); yourFunction(someParam)}}>Delete</Button>
Run Code Online (Sandbox Code Playgroud)
这是不是100%完美,但如果它要么是太痛苦的向下传递props的孩子- >儿童时装或创建Context.Provider/Context.Consumer 只用于此目的),而你处理的是有它自己的处理器运行的另一个库在你之前,你也可以尝试:
function myHandler(e) {
e.persist();
e.nativeEvent.stopImmediatePropagation();
e.stopPropagation();
}
Run Code Online (Sandbox Code Playgroud)
据我了解,该event.persist方法可防止对象立即被扔回 React 的SyntheticEvent池中。因此,event当您到达 React 时,传入的 React 实际上并不存在!这发生在孙子中是因为 React 在内部处理事情的方式是首先检查父级的SyntheticEvent处理程序(特别是如果父级有回调)。
只要您不调用persist会产生重要记忆的东西来继续创建事件onMouseMove(并且您没有创建某种 Cookie Clicker 游戏,例如 Grandma's Cookies),它应该完全没问题!
另请注意:通过偶尔阅读他们的 GitHub,我们应该密切关注 React 的未来版本,因为他们最终可能会解决一些与此有关的痛苦,因为他们似乎打算在编译器/转译器中制作折叠 React 代码。
如果您希望发生嵌套元素中的操作而不是父元素中的操作,那么,您可以从父元素的操作处理程序中检查目标的类型,然后基于该类型执行操作,即如果目标是我们的嵌套元素,我们什么也不做。否则两个处理程序都会被调用。
// Handler of the parent element. Let's assume the nested element is a checkbox
function handleSingleSelection(e) {
if(e.target.type !== 'checkbox') {
// We do not do anything from the
// parent handler if the target is a checkbox ( our nested element)
// Note that the target will always be the nested element
dispatch(lineSelectionSingle({ line }))
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
64681 次 |
| 最近记录: |