【问题标题】:Prevent event from bubbling up the dom tree防止事件冒泡 dom 树
【发布时间】:2020-03-16 09:13:43
【问题描述】:

我有一个卡片组件如下

<div
      onClick={e => {
        console.log("DEMAND CARD CLICKED");
        if (isSelectionActive) {
          setSelected();
        }
      }}
>  
      <DemandCardFooter
        demandId={id}
        totalBooked={totalBooked}
        totalDemand={totalDemand}
      />    
</div>

这是&lt;DemandCardFooter/&gt; 的样子:

<div className="vt-card-footer d-flex justify-content-between align-items-baseline px-3">
      <DemandSelector demandId={demandId} />
      <p className="lead font-weight-bold mb-0">
        <span className="text-success">{totalBooked}</span> / {totalDemand}{" "}
        <small className="text-muted font-weight-normal">Units.</small>
      </p>
</div>

最后这就是&lt;DemandSelector/&gt; 的样子:

const DemandSelector = ({ demandId }) => {
  const [isChecked, setChecked] = useRowSelector({
    path: "demands",
    payload: { id: demandId }
  });
  return (
    <Checkbox
      checked={isChecked ? true : false}
      onClick={e => {
        console.log("CHECKBOX CLICKED");
        e.stopPropagation();
        e.nativeEvent.stopImmediatePropagation();
        setChecked();
      }}
    />
  );
};

我的问题是当我点击复选框时,复选框的onClick 和卡片的onClick 都被触发了,有什么办法可以将回调限制在最低级别?

【问题讨论】:

  • e.stopPropagation(); 有什么问题我可以看到您在代码中使用了它。它应该防止事件传播。

标签: javascript reactjs event-handling dom-events event-bubbling


【解决方案1】:

这不是事件冒泡的问题,问题在于事件捕获阶段。

事件停止冒泡,您在代码中使用了e.stopPropagation();。但是在父事件中不会阻止事件捕获。

您可以通过在父事件中添加e.stopPropagation(); 来阻止它。

<div
      onClick={e => {
         e.stopPropagation();
        console.log("DEMAND CARD CLICKED");
        if (isSelectionActive) {
          setSelected();
        }
      }}
    >
      <DemandCardFooter
        demandId={id}
        totalBooked={totalBooked}
        totalDemand={totalDemand}
      />
    </div>

【讨论】:

  • 试过了,还是不行,我遇到了同样的问题
  • 您使用的是哪个反应版本?这可能是一个错误。
  • 我正在使用 React v16.12.0
【解决方案2】:

过了一会才明白。解决方案是将stopPropogation() 放入封装&lt;DemandSelector/&gt; 的DOM 元素中

所以这段代码有效

 <div
      className="vt-card-footer d-flex justify-content-between align-items-baseline px-3"
      onClick={e => {
        e.stopPropagation();
      }}
    >
      <DemandSelector demandId={demandId} />
      <p className="lead font-weight-bold mb-0">
        <span className="text-success">{totalBooked}</span> / {totalDemand}{" "}
        <small className="text-muted font-weight-normal">Units.</small>
      </p>
    </div>

也别忘了把它一直放下去

const DemandSelector = ({ demandId }) => {
  const [isChecked, setChecked] = useRowSelector({
    path: "demands",
    payload: { id: demandId }
  });

  return (
    <Checkbox
      checked={isChecked ? true : false}
      onClick={e => {
        e.stopPropagation();
        setChecked();
      }}
    />
  );
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 2010-12-20
    • 2020-04-24
    • 2018-07-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多