최상위 컴포넌트 (LayOut.tsx와 같은)에 modal을 props로 넘겨주고 모달을 띄우고 싶은 컴포넌트에 모달 상태 관리(useState)를 사용해서 모달 띄우기
파일 구조

import React, { ReactNode } from "react";
import styled from "styled-components";
import { useRouter } from "next/router";
import Footer from "./Footer";
import Header from "./Header";
import SearchHeader from "../components/SearchHeader";
// import WriteHeader from "../components/WriteHeader";
import PageTransition from "../components/PageTransition/PageTransition";
import CommentFooter from "../components/CommentFooter";
interface MainLayoutProps {
children: ReactNode;
modal?: ReactNode; // modal 속성 추가
}
const MainLayout: React.FC<MainLayoutProps> = ({ children, modal }) => {
const router = useRouter();
// 특정 경로에서는 Header와 Footer 렌더링 안 함
const hideHeader =
router.pathname === "/search" ||
router.pathname === "/write" ||
router.pathname === "/" ||
router.pathname === "/signup";
const showSearchHeader = router.pathname === "/search";
const showWriteHeader = router.pathname === "/write";
const hideFooter = router.pathname === "/";
const commentFooter =
router.pathname === "/" ||
router.pathname === "/write" ||
router.pathname === "/search";
return (
<>
<PageTransition>
<Main>
{children}
{modal}
</Main>
</PageTransition>
</>
);
};
export default MainLayout;
const Main = styled.main`
display: flex;
flex-direction: column;
max-width: 430px;
margin: 0 auto;
min-height: calc(100vh - 50px);
height: 100%;
@media (min-width: 375px) {
width: 430px;
}
@media (max-width: 500px) {
width: 100vw;
}
`;
import React, { useState } from "react";
import styled from "styled-components";
import { useRouter } from "next/router";
import ReadingGlasses from "../assets/header/ReadingGlasses.svg";
import VericalDot from "../assets/header/VerticalDots.svg";
import Back from "../assets/header/Back.svg";
import GoBack from "../assets/header/GoBack.svg";
import Link from "next/link";
import EditModal from "../pages/modal/edit/EditModal"; // 모달 컴포넌트 가져오기
interface FooterProps {
token: string | undefined;
}
const Header: React.FC<FooterProps> = ({ token }) => {
const router = useRouter();
const ShowBack = router.pathname === "/content";
const Home = router.pathname === "/";
// '/main'에 정확히 일치하는지 여부와 '/main/contents/*' 경로 구분
const isContentsPage = router.pathname.startsWith("/main/contents");
// 모달 상태 관리
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<HeaderContainer>
<HeaderBack onClick={() => router.push(`/main/${token}`)}>
{ShowBack ? <Back /> : !Home && <GoBack />}
</HeaderBack>
<HeaderItem>
자유게시판
<HeadersubItem>상명대 천안캠</HeadersubItem>
</HeaderItem>
<HeaderBt>
<Link href={`/search?token=${token}`}>
<HeaderRG>
<ReadingGlasses />
</HeaderRG>
</Link>
{/* '/main'에서는 HeaderVD만 렌더링, '/main/contents/*'에서는 클릭 이벤트 포함 */}
{isContentsPage ? (
<HeaderVD onClick={() => setIsModalOpen(true)}>
<VericalDot />
</HeaderVD>
) : (
<HeaderVD></HeaderVD>
)}
</HeaderBt>
{/* 모달이 열려 있을 때만 렌더링 */}
{isModalOpen && <EditModal token={token} />}
</HeaderContainer>
);
};
export default Header;
const HeaderContainer = styled.div`
display: flex;
position: sticky;
text-align: center;
width: 100%;
height: 50px;
top: 0;
background-color: white;
`;
const HeaderBack = styled.div`
margin-top: 18px;
margin-left: 3%;
width: 20px;
`;
const HeaderItem = styled.div`
flex-direction: column;
font-size: 13px;
width: 100%;
background-color: white;
display: flex;
padding-top: 12px;
padding-left: 70px;
`;
const HeadersubItem = styled.div`
font-size: 13px;
color: gray;
`;
const HeaderBt = styled.div`
margin-right: 5%;
margin-top: 20px;
display: flex;
gap: 30px;
`;
const HeaderRG = styled.div``;
const HeaderVD = styled.div``;
import { useRouter } from "next/router";
import React from "react";
import styled from "styled-components";
interface EditModalProps {
token: string | undefined;
}
const EditModal: React.FC<EditModalProps> = ({ token }) => {
const router = useRouter();
return (
<ModalOverlay>
<ModalContent>
<h2>Edit Modal</h2>
<p>내용을 수정할 수 있습니다.</p>
<button onClick={() => router.back()}>닫기</button>
</ModalContent>
</ModalOverlay>
);
};
export default EditModal;
const ModalOverlay = styled.div`
position: fixed;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
background-color: rgba(0, 0, 0, 0);
display: flex;
justify-content: center;
align-items: center;
`;
const ModalContent = styled.div`
background-color: white;
padding: 20px;
border-radius: 10px;
width: 400px;
text-align: center;
`;
MainLayout에서 modal을 props로 넘겨주고 Header.tsx에서 모달 상태관리를 통해 해당 버튼을 누르면 초깃값이 false였던게 true로 바뀌면서 모달 컴포넌트(EditModal.tsx)를 띄움