阻止事件传播到 children

Prevent event from propagating to children

我正在构建一个 React 组件以包裹其他组件,这些组件将 grey-out children 并(希望)使它们对点击无反应。

我的做法是:

const TierGater: React.FC = (props) => {
  const handleTierGaterClick = (e: React.MouseEvent<HTMLDivElement>) => {
    console.log("outer - should be called");
    // e.stopPropagation();
    // e.preventDefault();
  };

  return (
    <div onClick={handleTierGaterClick}>
      <div
        onClick={() => {
          console.log("inner - should not be called");
        }}
      >
        {props.children}
      </div>
    </div>
  );
};

export default TierGater;

我希望这是一个通用的解决方案,允许我任意包装组件而无需修改 children 个组件的 onClick。

我浏览了各种解决方案,但我的理解是事件处理程序将从 children 到 parents 顺序触发。上述示例的控制台日志证实了这一点(首先调用内部)。

我相信我可以更改 children 以检查事件目标并基于此中止 onClick 逻辑,但这违背了组件的目的 - 它应该环绕任何 children 而无需修改children.

以上可能吗?如果是,需要引入哪些变化?

附带问题:我的事件处理程序是用 React.MouseEvent<HTMLDivElement> 输入的 - 我怎样才能使它同时处理鼠标和触摸事件?

使用 onClickCapture,您可以在捕获阶段拦截事件,在事件传给子级之前阻止它们传播:

<div onClickCapture={handleTierGaterClick}>
const handleTierGaterClick = (e: React.MouseEvent<HTMLDivElement>) => {
  e.stopPropagation();
  e.preventDefault();
};

为了更 UI 友好,褪色的背景或许 pointer-events: none 也不错。