【问题标题】:React Modal only close when I click background or close icon?React Modal 仅在我单击背景或关闭图标时关闭?
【发布时间】:2020-10-19 05:09:19
【问题描述】:

这是一个代码笔https://codesandbox.io/s/amazing-morning-ukxp2?file=/src/App.js

所以我创建了这个模态,并用Background 样式的组件包装了它,但我不知道如何让关闭功能仅在我只单击背景或关闭图标时才起作用。

现在我的整个模式都被这个background 包裹着,所以无论我在哪里点击它总是会关闭。我只希望它在我点击BackgroundCloseModalButton 时关闭,而不是在我点击我的实际模式时关闭。

下面是我的代码

      export const Modal = ({ showModal, setShowModal }) => {
        const animation = useSpring({
          opacity: showModal ? 1 : 0,
          transform: showModal ? `translateY(0%)` : `translateY(-200%)`
        });

        return (
          <>
            {showModal ? (
              <Background onClick={() => setShowModal(!showModal)}>
                <animated.div style={animation}>
                  <ModalWrapper showModal={showModal}>
                    <div>hi</div>
                    <CloseModalButton
                      aria-label='Close modal'
                      onClick={() => setShowModal(!showModal)}
                    />
                  </ModalWrapper>
                </animated.div>
              </Background>
            ) : null}
          </>
        );
      };

然后这里是我的App.js,带有打开和关闭模态的功能

    function App() {
      const [showModal, setShowModal] = useState(false);

      const openModal = () => {
        setShowModal(!showModal);
      };

      return (
        <Container>
          <Button onClick={openModal}>Aye what's good</Button>
          <Modal showModal={showModal} setShowModal={setShowModal} />
          <GlobalStyle />
        </Container>
      );
    }

主要问题是背景包裹了我的整个模态,所以我需要一种方法来仅在目标是实际背景或 X 图标而不是实际模态本身(包裹在背景)

【问题讨论】:

  • 你能重现codesandbox中的输出吗?
  • 这与您的问题无关,但是在切换模式时,您应该使用setShowModal 的先前状态,例如:setShowModal(prev =&gt; !prev)
  • @Scratch'N'Purr prev 和将状态切换到与 !showModal 值相反的状态有什么区别?
  • @JuliusGuevarra 我在上面添加了代码框的链接

标签: reactjs


【解决方案1】:

您需要跟踪event.target,它给出了被调用的位置,即

const closeModal = (event) => {
    const modal = document.getElementById("myModal");
    if (event.target === modal) {
      setShowModal(false);
    }
  };
<Background id="myModal" onClick={closeModal}>

这里是演示:https://codesandbox.io/s/cranky-hodgkin-o77em?file=/src/components/Modal.js

【讨论】:

  • 我希望背景关闭模式以及关闭图标。所以这就是我同时添加它的原因,但问题是无论我点击哪里,背景都会关闭它,因为它包含了所有内容
  • 你的意思是模态的背景还是模态之外的?
  • 是的,只有模式的外部,或者关闭图标。如果你增加屏幕的 with ,你会看到我的 X 图标
  • 在 react 中使用 id 好不好?你知道是否可以使用 useRef 来代替吗?
  • 还要检查console.log,因为关闭模态时出现错误
【解决方案2】:

问题是由于事件冒泡造成的。每次单击 Background 元素的任何后代时,它们的单击处理程序都会触发并冒泡,直到到达触发自身处理程序的 Background 元素。为了解决这个问题,您可以使用 stopPropagation() 方法停止子元素的点击处理程序的传播,或者您可以简单地将 ID 添加到背景并确定 id 是否与背景匹配,然后触发showModal 方法。

&lt;Background onClick={closeModal} id="bg"&gt;

const closeModal = (e) => {
    if (e.target.id === 'bg') {
      setShowModal(false);
    }
  };

没有必要为关闭按钮添加 id 并检查目标按钮的 id,因为单击按钮肯定会关闭模式。

【讨论】:

  • 将 id 与 react 一起使用是最佳实践吗?没有办法用 useRef 做同样的事情吗?
  • 另外,当我尝试关闭模式时,我的控制台出现错误
猜你喜欢
  • 1970-01-01
  • 2022-06-29
  • 2021-02-12
  • 2015-09-14
  • 2022-12-08
  • 2020-10-15
  • 2017-10-19
  • 2022-08-14
相关资源
最近更新 更多