072DATA

모달창 만들기(리액트, TypeScript) 본문

FrontEnd/TypeScript

모달창 만들기(리액트, TypeScript)

0720 2024. 10. 10. 07:34

프로젝트를 진행하면서 간단하게 모달창을 구현해 보았다

 

라이브러리를 설치하여 모달 창을 만드는 방법도 있었지만 직접 만들어 보고 싶었다!

 

모달 컴포넌트

import { ModalTypeC } from "@/types/modal";
import React from "react";
import styled from "styled-components";

const Modal: React.FC<ModalTypeC> = ({ isModalOpen, closeModal, children }) => {
  if (!isModalOpen) return null;

  return (
    <ModalOverlay onClick={closeModal}>
      <ModalContent onClick={(e) => e.stopPropagation()}>
        {children}
      </ModalContent>
    </ModalOverlay>
  );
};

export default Modal;

 

먼저 Modal 컴포넌트를 만들어 주는데  함수형 컴포넌트를 명시하는 부분이 중요하지 않나 싶다

 

children prop이 자동으로 타입이 지정되어 타입스크립트가 올바르게

타입을 추론할 수 있게 되어 별도로 타입을 지정해줄 필요도 없다

 

또 콘텐츠 영역 밖을 클릭하면 모달창이 꺼지도록 onClick을 설정해주었다

 

모달 CSS 설정

const ModalOverlay = styled.div`
  position: fixed;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background-color: rgba(176, 184, 196, 0.5);
  display: flex;
  justify-content: center;
  align-items: center;
`;

const ModalContent = styled.div`
  background-color: white;
  padding: 15px;
  border-radius: 8px;
  box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
`;

 

스타일드 컴포넌트를 사용해서 화면 정 가운데에서 렌더링 되도록 지정해주었다

 

모달 컴포넌트를 사용하는 부모 컴포넌트

const Header = () => {
  const { isModalOpen, modalType, openModal, closeModal } = useModalStore();

  return (
	//...코드 생략
      <Modal isModalOpen={isModalOpen} closeModal={closeModal} modalType={modalType}>
        {modalType === "signin" && <SignInPage />}
        {modalType === "signup" && <SignUpPage />} 
      </Modal>
    </header>
  );
};

export default Header;

 

다음은 헤더에서 모달창을 열 때 설정이다 modalType에 따라서

로그인 페이지를 열거나 회원가입 페이지를 열도록 설정해주었다

 

모달에 관련된 상태 관리는 zustand를 사용해서 관리해주었다

 

모달 타입

export interface ModalTypeA {
  isModalOpen: boolean;
  closeModal: () => void;
  modalType: "signin" | "signup" | null;
}

export interface ModalTypeB extends ModalTypeA {
  openModal: (type: "signin" | "signup") => void;
}
export interface ModalTypeC extends ModalTypeA {
  children: React.ReactNode;
}

 

타입이 중복으로 사용하는 부분이 있어서 extends로 타입을 확장시켜

재사용성을 높였다 사실 유틸리티 타입을 사용하면 이 방법도 굳이 안써도 될 것 같은데

일단은 구현은 해야하니 나중에 리팩토링 해보는 걸로 해야겠다

 

결과물

 

 

이제 캠프도 한 달 반정도 남았는데.. 점점 압박감이 생긴다

진짜 이제 영혼까지 갈아서 불태워야겠다..!!!! 제발 화이팅..

'FrontEnd > TypeScript' 카테고리의 다른 글

TodoList 만들기  (1) 2024.09.26
TypeScript 타입 선언하는 방법  (0) 2024.09.25
타입스크립트 요약  (0) 2024.09.24