【发布时间】:2017-12-02 12:41:30
【问题描述】:
我在组件中嵌套了点击事件处理程序:
class ListItem extends React.Component {
...
render() {
return (
<div onClick={this.save}>
...Content...
<span onClick={this.onDeleteClick}> (Delete)</span>
</div>
);
}
...
}
(完整的,本文底部的最小示例。)
此组件用作包含组件中的“列表项”。当我单击(Delete) 时,它会按预期触发onDeleteClick,这会回调父组件,从而导致组件从父组件中删除。正如预期的那样,点击事件然后开始冒泡。但是,它会“向上”冒泡到 父列表中的下一个组件。毕竟,原来的目标已经被删除处理程序删除了。
如果我将 e.stopPropagation() 添加到 onDeleteClick 处理程序的顶部,一切正常,但我只是想了解 为什么 click 事件被传递到一个完全不同的组件,只是为了确保那里没有任何其他确凿证据。
我目前的理论是,挂起的事件队列以某种方式被索引到虚拟 DOM 中,如果您在事件处理程序期间改变虚拟 DOM,冒泡事件可能会传递到虚拟 DOM 中的错误组件。我本来希望冒泡事件只是不触发,而不是在完全不同的组件上触发。
这是怎么回事?还有其他见解吗?这是一个有缺陷的设计吗?如果有,有什么替代方案的建议吗?
这是一个显示问题的最小示例:https://codepen.io/mgalgs/pen/dRJJyB
这是固定版本:https://codepen.io/mgalgs/pen/KqZBKp
“修复”的完整差异是:
--- orig.jsx
+++ new.jsx
@@ -32,6 +32,7 @@
}
onDeleteClick(e) {
+ e.stopPropagation();
this.props.onDeleteClick(e);
}
}
【问题讨论】:
-
实际上,这真的很好奇:codepen.io/anon/pen/rwpZNK?editors=1111 --- 如果您检查 CodePen 控制台,它似乎正确地冒泡到正确的父级,但如果您检查开发者控制台,它会冒泡到错误的父母。
-
我怀疑因为 react 依赖于键,它实际上可能会将其推送到“下一个”元素,因为它现在占据了原始删除的元素
标签: javascript reactjs events virtual-dom