React로 Modal창 만들기

돌리의 하루·2023년 2월 21일
1

모달 창을 만들 때는 어떤 상태가 필요할까요?🐼
모달을 열고 닫을 때 관리해주는 state가 필요할겁니다!

모달에 필요한 css와 react 구문을 살펴보면서, 알아가게 된 부분을 같이 적어보겠습니다🐥

우선 css 부분과 react 구현 부분을 잘라서 보자면,

import { useState } from "react";
import styled from "styled-components";

export const ModalContainer = styled.div`
  display: flex;
  justify-content: center;
  align-items: center;
  height: 300px; //높이가 있어야 중앙으로 정렬하게 된다!
`;

export const ModalBackdrop = styled.div`
  position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.5);
  width: 100%;
  height: 100%;
`;

export const ModalBtn = styled.button`
  background-color: var(--coz-purple-600);
  text-decoration: none;
  border: none;
  padding: 20px;
  color: white;
  border-radius: 30px;
  cursor: grab;
`;

export const ModalView = styled.div.attrs((props) => ({
  // attrs 메소드를 이용해서 아래와 같이 div 엘리먼트에 속성을 추가할 수 있습니다.
  role: "dialog",
}))`
  border-radius: 20px;
  width: 300px;
  height: 200px;
  background-color: white;
  display: flex;
  align-items: center;
  justify-content: center;
  flex-direction: column; 
  //버튼과 모달 안의 내용물이 수평정렬이라 보기싫어서 수직으로 정렬했다

  > button {
    font-size: 30px;
    color: pink;
    border: none;
    background-color: rgba(0, 0, 0, 0);
    margin-top: 10px;
  }
`;
  • ModalContainer을 보면, height로 높이를 주었는데요,
    height을 주게 되어야 modalbutton을 감싸고 있는 부모영역에 높이를 주게되어서 버튼이 정렬 되는 것을 확인할 수 있습니다.

  • ModalBackdrop에서 살펴볼 점은,
position: fixed;
  left: 0;
  right: 0;
  top: 0;
  bottom: 0;
  display: flex;
  justify-content: center;
  align-items: center;
  background-color: rgba(0, 0, 0, 0.5);

뒷배경이 ModalBackdrop인데요,
여기서 뒷배경이 화면에 꽉차고 scroll해도 fixed되는 모습과, 상하좌우를 모두 0으로 주면서 화면을 꽉 채우게 되는 모습을 볼 수 있습니다😗

밑으로는 구현코드 입니다!

export const Modal = () => {
  const [isOpen, setIsOpen] = useState(false);

  const openModalHandler = () => {
    setIsOpen(!isOpen);
  };

  return (
    <>
      <ModalContainer>
        <ModalBtn
          onClick={openModalHandler}
        >
          {isOpen ? "Opened!" : "OpenModal"}
        </ModalBtn>
       
        {isOpen === false ? null : (
          <ModalBackdrop onClick={openModalHandler}>
            <ModalView onClick={(e) => e.stopPropagation()}>
              <div>Hello my name is Mango</div>
              <button onClick={openModalHandler}>x</button>
            </ModalView>
          </ModalBackdrop>
        )}
      </ModalContainer>
    </>
  );
};
  • setIsOpen(!isOpen)으로 모달이 닫히고 열리는 부분을 구현했습니다

  • {isOpen ? "Opened!" : "OpenModal"}으로 열고 닫힘에 따르는 버튼내용을 구성했습니다

  • <ModalView onClick={(e) => e.stopPropagation()}> 이 부분에서 ModalView는 상위컴포넌트인 ModalBackdrop의 onClick 컨텐츠를 상속받아, onClick이벤트를 따로 구현하지 않아도 ModalView를 누르면 모달이 닫히는 모습을 볼 수 있습니다🧐
    이런 현상을 이벤트버블링이라고 부릅니다.

위 사진의 버튼과 글을 감싸고 있는 부분이 ModalView입니다.
닫힘버튼이나 뒷배경을 누르지 않아도 닫히면, 느낌이 이상하겠죠..!
그래서 상속받은 onClick 이벤트를 막고, 이벤트를 방지하기 위해서

onClick={(e) => e.stopPropagation()

이 기능을 추가한 것입니다!😎👍

profile
진화중인 돌리입니다 :>

0개의 댓글