React:stopPropagation()似乎不起作用?

问题描述 投票:1回答:2

我有一个页脚组件,该组件具有切换模式组件的功能。在模态组件中,我有一个背景包装器,而模态嵌套在该包装器中。我已经将toggleModal函数设置为prop,并将其添加到模式包装器中。我不希望模态本身分配有此click函数,因此尽管似乎不起作用,但我在函数中使用了stopPropagation()来停止事件冒泡。

页脚组件:

const Footer = () => {
  const [showModal, setShowModal] = useState(false);

  function toggleModal(e) {
    e.stopPropagation();
    setShowModal(!showModal);
  }
  return (
    <div>
      <button onClick={toggleModal}>Modal toggle</button>
      <Modal show={showModal} toggle={toggleModal}>This is a modal</Modal>
    </div>
  )
}

模式组件:

const Modal = () => {
  return (
   <div className="modal__wrapper" onClick={props.toggle}>
     <div className="modal p-3">
       <div className="modal__close" onClick={props.toggle} role="button" aria-hidden="true">
         X
       </div>
       {props.children}
     </div>
   </div>
  )
}
javascript reactjs stoppropagation
2个回答
0
投票

尽管似乎不起作用,但可以阻止事件冒泡。

您是说事件冒泡不起作用,还是模态通常不起作用?我发现了两个代码问题,这些问题在修复后似乎可以使模态工作。另外,您may想要e.preventDefault()的行为,但是我不确定您的问题。

问题和修复:

  1. 方法签名中缺少道具:const Modal = (props) => {
  2. 未使用show属性显示/隐藏模式div:props.show && <div className="modal__wrapper" onClick={props.toggle}>

stopPropagation&preventDefault

要查看stopPropagationpreventDefault的行为差异,请尝试将此radio添加到按钮下方。每次需要重置radio进行实验时,都需要刷新页面。

<input type="radio" name="gender" value="male" onClick={toggleModal}/>

[preventDefault停止设置radio,它防止无线电组件的默认行为设置值。

stopPropagation不是停止设置radio,因为它只停止冒泡到父元素的事件。在text <input>上有用,可以防止Enter键之类的事件影响要提交的父<form>元素(如果需要)。

我希望这有助于解决您的问题。


0
投票

发生的事情:

  1. .modal或其中的另一个元素被单击。没有侦听器附加到该元素,因此事件继续冒泡直到祖先。
  2. 事件到达.modal__wrapper,该事件具有click事件的侦听器。侦听器不会区分哪个元素是事件的直接目标:元素本身或其后代之一。即使目标是包装器内的另一个元素,也会触发props.toggle()。侦听器停止传播。事件停止冒泡,但是树上没有人听得更高。

我建议您将引用附加到包装器,并检查事件目标是否是包装器本身。

模态组件看起来像这样:

const Modal = (props) => {
  const wrapperRef = useRef();

  const handleClick = e => {
    if(e.target === wrapperRef.current) {
      props.toggle(e);
    }
  };

  return (
   <div className="modal__wrapper" onClick={handleClick} ref={wrapperRef}>
     <div className="modal p-3">
       <div className="modal__close" onClick={props.toggle} role="button" aria-hidden="true">
         X
       </div>
       {props.children}
     </div>
   </div>
  );
};
© www.soinside.com 2019 - 2024. All rights reserved.