简体   繁体   English

如何在 React 中处理不同位置的多个模态?

[英]How to handle multiple modals at different positions in React?

I am creating a portfolio site using Next Js.我正在使用 Next Js 创建一个投资组合网站。

I have a work section which consists of a screenshot of the projects.我有一个工作部分,其中包含项目的屏幕截图。 These are placed towards the left/right of the screen alternatively (refer screenshot attached).它们交替放置在屏幕的左侧/右侧(请参阅随附的屏幕截图)。

I want to have a modal (explaining the project, links to code, tech stack used, etc) that pops up in the middle of the screenshot div (like in the pic attached) when a particular project's screenshot is clicked on.我想要一个模式(解释项目、代码链接、使用的技术堆栈等),当单击特定项目的屏幕截图时,它会在屏幕截图 div 的中间弹出(如附图所示)。

But the problem is, Every other project's modal gets triggered too.但问题是,每个其他项目的模式也会被触发。 I want only that particular modal to pop up.我只想弹出那个特定的模式。

Before Clicking on Screenshot:点击截图之前: 点击截图之前

After Clicking on Screenshot:点击截图后: 点击截图后

I had faced a similar issue on another project when all modals in the page gets triggered, but I could fix it by passing modal content data using an arrow function as all modals were rendered in the center of the screen.当页面中的所有模态都被触发时,我在另一个项目中遇到了类似的问题,但我可以通过使用箭头 function 传递模态内容数据来修复它,因为所有模态都在屏幕中央呈现。
But for this, the Modals are positioned differently for each project.但是为此,每个项目的模式定位不同。 I'm not sure how to code them into place.我不确定如何将它们编码到位。

Here's my code:这是我的代码:

WorkItemsDesk.js WorkItemsDesk.js

export const WorkItemsDesk = () => {
  const [showModal, setShowModal] = useState(false);
  const togglePopUp = () => setShowModal(!showModal);

  return (
    <div className="flex flex-col my-[100px] gap-[100px] z-10 ">
      {projects.map((project) => (
        <div
          key={project.title}
          onClick={() => togglePopUp()} //This is so the modal closes when clicked outside
          className="w-[1000px] z-20 hover:cursor-pointer relative bg-no-repeat bg-center bg-fixed bg-clip-border bg-contain h-[470px] flex justify-center items-center odd:ml-auto hover:shadow-2xl transition-all duration-300 ease-in-out"
          style={{
            background: `linear-gradient(0deg, rgba(4, 4, 4, 0.65), rgba(4, 4, 4, 0.65)), url(${project.image});`,
            backgroundClip: "border-box",
            backgroundRepeat: "no-repeat",
            backgroundPosition: "center",
            backgroundSize: "cover",
          }}
        >
          <h1 className="font-montserrat-extrabold text-[40px] text-light-text">
            {project.title}
          </h1>
          <WorkModalDesk project={project} showModal={showModal} />
        </div>
      ))}
    </div>
  );
};

WorkModalDesk.js WorkModalDesk.js

export const WorkModalDesk = ({
  project: { p1, p2, tech, sourceCode, liveDemo, buttons },
  showModal,
}) => {
  return (
    <div
      className={
        showModal
          ? "flex pt-[24px] absolute px-[30px] pb-[34px] bg-dark rounded-lg flex-col gap-[40px] max-w-[450px] "
          : "hidden"
      }
    >
      <p className="text-[18px] text-light-text font-montserrat">
        {p1}
        <span className="block mt-[28px]">{p2}</span>
      </p>
      .
      .
      .
      .
    </div>
  );
};

The reason all your modals are displayed at once is that you have a single state to manage all rendered modals.一次显示所有模态的原因是您有一个 state 来管理所有呈现的模态。

I would suggest to move the loop outside of WorkItemDesk component as follows:我建议将循环移到WorkItemDesk组件之外,如下所示:

export const WorkItemsDesk = () => {
  const [showModal, setShowModal] = useState(false);
  const togglePopUp = () => setShowModal((prev) => !prev);

  return (
    <div className="flex flex-col my-[100px] gap-[100px] z-10 ">
      <div
          onClick={() => togglePopUp()} //This is so the modal closes when clicked outside
          className="w-[1000px] z-20 hover:cursor-pointer relative bg-no-repeat bg-center bg-fixed bg-clip-border bg-contain h-[470px] flex justify-center items-center odd:ml-auto hover:shadow-2xl transition-all duration-300 ease-in-out"
          style={{
            background: `linear-gradient(0deg, rgba(4, 4, 4, 0.65), rgba(4, 4, 4, 0.65)), url(${project.image});`,
            backgroundClip: "border-box",
            backgroundRepeat: "no-repeat",
            backgroundPosition: "center",
            backgroundSize: "cover",
          }}
        >
          <h1 className="font-montserrat-extrabold text-[40px] text-light-text">
            {project.title}
          </h1>
          <WorkModalDesk project={project} showModal={showModal} />
        </div>
    </div>
  );
};

Then in the parent component of WorkItemDesk add your projects loop as follows:然后在WorkItemDesk的父组件中添加您的项目循环,如下所示:

export const Parent = () => (
  <>
   {projects.map((project) => (
        <WorkItemDesk key={project.title} />
      ))}
  </>
)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM