使用reactjs打开选定的模态

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

我在这个question上使用代码共享

代码只适用于一个模态,我试图添加不止一次但是当我第一次点击它打开所有模态都是触发器,然后它正常工作,这是我面临的唯一问题

Modal.js

import React, { useRef, useEffect } from "react";
import { createPortal } from "react-dom";

const Modal = ({ isOpen, type, onClose, children }) => {
  const modalEl = useRef(null);
  const handleCoverClick = e => {
    if (e.target.hasAttribute("modal")) {
      onClose();
    }
  };

  useEffect(() => {
    const handleAnimationEnd = event => {
      if (isOpen.type === type && isOpen.modal) {
        if (!isOpen.modal) {
          event.target.classList.remove("show");
          event.target.classList.add("hide");
        } else {
          event.target.classList.remove("hide");
          event.target.classList.add("show");
        }
      }
    };
    modalEl.current.addEventListener("animationend", handleAnimationEnd);

    return () =>
      modalEl.current.removeEventListener("animationend", handleAnimationEnd);
  }, [isOpen]);

  return createPortal(
    <>
      <div
        className={`ModalCover ${isOpen ? "show" : "hide"}`}
        onClick={handleCoverClick}
        modal="true"
      />
      <div
        className={`
            ModalContainer
            ${isOpen.type === type && isOpen.modal ? "slide-up" : "slide-down"}
            ${!modalEl.current && "hide"}
            `}
        ref={modalEl}
      >
        {children}
      </div>
    </>,
    document.body
  );
};

export default Modal;

style.css文件

.App {
  font-family: sans-serif;
  text-align: center;
}

.show {
  display: block;
}

.hide {
  display: none;
}

.slide-up {
  transform: translateY(0%);
  animation: slide-up 0.5s forwards;
}

.slide-down {
  transform: translateY(100%);
  animation: slide-down 0.5s forwards;
}

@keyframes slide-up {
  0% {
    transform: translateY(100%);
  }
  100% {
    transform: translateY(0%);
  }
}

@keyframes slide-down {
  0% {
    transform: translateY(0%);
  }
  100% {
    transform: translateY(100%);
  }
}

.ModalCover {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  z-index: 10;
  background-color: rgba(0, 0, 0, 0.15);
}

.ModalContainer {
  position: fixed;
  top: 0;
  left: 0;
  width: 100%;
  height: 400px;
  margin-top: calc(100vh - 400px);
  z-index: 20;
}

Index.js

import React, { useState } from "react";
import ReactDOM from "react-dom";

import Modal from "./Modal";

import "./styles.css";

function App() {
  const [isOpen, setIsOpen] = useState(false);
  return (
    <div className="App">
      <Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
        <div>
          <h3>Coockie</h3>
          <p>content about coockies</p>
          <button
            aria-label="Close this popup"
            onClick={() => setIsOpen({ type: "coockie", modal: false })}
            className="closeBtn"
          >
            x
          </button>
        </div>
      </Modal>

      <Modal isOpen={isOpen} onClose={() => setIsOpen(false)}>
        <div>
          <h3>About us</h3>
          <p>content about us</p>
          <button
            aria-label="Close this popup"
            onClick={() => setIsOpen({ type: "about-us", modal: false })}
            className="closeBtn"
          >
            x
          </button>
        </div>
      </Modal>

      <button onClick={() => setIsOpen({ content: "coockie", modal: true })}>
        coockie modal
      </button>
      <button onClick={() => setIsOpen({ content: "about-us", modal: true })}>
        about us modal
      </button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);
  • 现场代码是here
  • 而这个link的代码使用一个模态
reactjs
1个回答
0
投票

更正: -

1)在isOpen为真之前,我们不想渲染模态

2)根据ModalContainer的标志更正显示和隐藏,而不是填写参考值modalEl.current中的当前值。

3)您对两个模态使用相同的状态和更新方法。创建单独的状态,你应该好好去。目前我有名字isOpen1isOpen2,但你可以给出更有意义的名字。

//index.就是

import React, { useState } from "react";
import ReactDOM from "react-dom";

import Modal from "./Modal";

import "./styles.css";

function App() {
  const [isOpen1, setIsOpen1] = useState(false);
  const [isOpen2, setIsOpen2] = useState(false);

  return (
    <div className="App">
      <>
        {isOpen1 && (
          <Modal isOpen={isOpen1} onClose={() => setIsOpen1(false)}>
            <div>
              <h3>Coockie</h3>
              <p>content about coockies</p>
              <button
                aria-label="Close this popup"
                onClick={() => setIsOpen1(false)}
                className="closeBtn"
              >
                x
              </button>
            </div>
          </Modal>
        )}
      </>
      <>
        {isOpen2 && (
          <Modal isOpen={isOpen2} onClose={() => setIsOpen2(false)}>
            <div>
              <h3>About us</h3>
              <p>content about us</p>
              <button
                aria-label="Close this popup"
                onClick={() => setIsOpen2(false)}
                className="closeBtn"
              >
                x
              </button>
            </div>
          </Modal>
        )}
      </>

      <button onClick={() => setIsOpen1(true)}>coockie modal</button>
      <button onClick={() => setIsOpen2(true)}>about us modal</button>
    </div>
  );
}

const rootElement = document.getElementById("root");
ReactDOM.render(<App />, rootElement);

// Modal.js

import React, { useRef, useEffect } from "react";
import { createPortal } from "react-dom";

const Modal = ({ isOpen, onClose, children }) => {
  const modalEl = useRef(null);
  const handleCoverClick = e => {
    if (e.target.hasAttribute("modal")) {
      onClose();
    }
  };

  useEffect(() => {
    const handleAnimationEnd = event => {
      if (!isOpen) {
        event.target.classList.remove("show");
        event.target.classList.add("hide");
      } else {
        event.target.classList.remove("hide");
        event.target.classList.add("show");
      }
    };
    const modalRef = modalEl.current;

    modalEl.current.addEventListener("animationend", handleAnimationEnd);

    return () =>
      modalRef.removeEventListener("animationend", handleAnimationEnd);
  }, [isOpen]);

  return createPortal(
    <>
      <div
        className={`ModalCover ${isOpen ? "show" : "hide"}`}
        onClick={handleCoverClick}
        modal="true"
      />
      <div
        className={`
          ModalContainer
          ${isOpen ? "slide-up show" : "slide-down hide"}
        `}
        ref={modalEl}
      >
        {children}
      </div>
    </>,
    document.body
  );
};

export default Modal;
© www.soinside.com 2019 - 2024. All rights reserved.