假设我有一个响应式 ReactJS 组件 (Outer
),当我单击它时会执行某些操作。在较大的组件中,我想要一个按钮,当我双击它时,它会做一些特别的事情。
export default function FancyDoubleClickHandler() {
function handleOuterClick() {
console.log("outer single click")
}
function handleInnerClick() {
???
}
return (
<div id="outer" onClick={handleOuterClick}>
<p>Click on me to do outer click</p>
<button id="inner" onDoubleClick={handleInnerClick}>
<p>
Click on me to do outer click -- OR --
Double-click on me to do special inner click thing only
</p>
</button>
</div>
)
}
正如所写,onDoubleClick
事件不会阻止外部 onClick
事件触发(两次)。这个基本问题在 this SO question 中得到解决,通过避免 onDoubleClick
而是使用统一的点击处理程序,该处理程序仅在超时到期后触发单次点击:
function handleAllClicks(event) {
clearTimeout(timer);
if (event.detail === 1) {
timer = setTimeout(() => {
console.log("SINGLE CLICK");
}, SOME_DOUBLECLICK_DELAY)
} else if (event.detail === 2) {
console.log("DOUBLE CLICK");
}
}
但是在那个答案中,不需要停止事件传播,因此双击内部按钮仍然会将两个点击事件传播到 handleOuterClick
。就我而言,我需要在双击的情况下抑制这些外部事件。
在(现代)ReactJS 中,如何实现内部元素拦截并处理双击,但向上传播单击的架构?
答案 0 :(得分:1)
您不能在内部元素的 onDoubleClick 事件中停止调用父元素的 onClick 事件。要停止事件传播,您应该在内部元素 onClick 事件处理程序中调用 event.stopPropagation() 并在其中模拟双击。我希望这对你有用:
function FancyDoubleClickHandler() {
let timer
function handleOuterClick() {
console.log("outer single click")
}
function handleInnerClick(e) {
e.stopPropagation();
clearTimeout(timer)
if (e.detail === 1) {
timer = setTimeout(() => {
handleOuterClick()
}, 250);
}
if(e.detail === 2) {
console.log("inner double click");
}
}
return (
<div id="outer" onClick={handleOuterClick}>
<p>Click on me to do outer click</p>
<button id="inner" onClick={handleInnerClick}>
<p>
Click on me to do outer click -- OR --
Double-click on me to do special inner click thing only
</p>
</button>
</div>
)
}