React - 모달 창 구현해보기(라이브러리 X)

밍글·2023년 3월 30일
1

⌨️서론

프로젝트를 하면서 한 가지 바꾸고 싶었던 부분이 있었다. 바로 alert부분을 기본으로 제공해주는 것이 아닌 커스텀 팝업창으로 바꾸어서 띄우고 싶었다. electron에서 alert창을 띄우면 약간 너무 'Electron'스러운 alert창이 뜨기 때문에 이 부분을 변경하고 싶었다.

그리고 또한 마이페이지 부분에서 닉네임이나 비밀번호 변경하는 모달이 필요하기 때문에 무조건 모달창을 구현해야만 했다.🔥그래서 이번에는 라이브러리를 사용하지 않고 모달 창을 구현해보도록 하겠다.🐥


모달 창 구현하기

먼저 모달 창을 만들기 위해 모달 창과 관련된 여러 styled-components를 만들어뒀다.

모달 창 구현에 있어 꼭 필요한 컴포넌트
1️⃣모달창 뒷부분을 어둡게 만들어주는 컴포넌트이다.
width와 height를 최대로 해두고 position을 fixed해둔 뒤 원하는 만큼의 어둡기를 background-color로 설정해준다.

export const MyModal = styled.div`
  background-color: rgba(0, 0, 0, 0.4);
  width: 100%;
  height: 100vh;
  z-index: 10;
  position: fixed;
  top: 0;
  left: 0;
`;

2️⃣모달창(화면 중앙, 최상단으로 노출)

  • 원하는 크기만큼 width와 height을 설정해 준 뒤, z-index를 최대한 높게 해준다.(본인의 경우에는 100만 줘도 최상단이기 때문에 이렇게 주었다.)
  • 그 다음 중앙배치를 위해서 position을 absolute로 해두고 top,left를 50%로 주면 된다. 또한 translate로 본인의 크기에 맞게 움직이게 하면 된다.
  • 그 이외의 속성은 본인이 원하는 모달창 css로 꾸며주면 된다.
export const MyPageModal = styled.div`
  width: 360px;
  height: 330px;
  z-index: 100;
  position: absolute;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  border-radius: 10px;
  box-shadow: 2px 2px 2px rgba(0, 0, 0, 0.25);
`;

이 이외의 모달창 내부에 필요한 컴포넌트들은 본인이 원하는 모양에 맞게 설계를 해 준 뒤 코드를 작성하면 된다. ‼️javascript와 달리 typescript의 경우에는 modalClose를 type으로 지정해 둔 뒤 매개변수로 넣어줘야 한다‼️

/*이 부분이 짧은 이유는 서버와 연동을 안 시켰기 때문이다.
매개변수의 수는 본인이 어떤 변수들을 모달 창에 넘기냐에 따라 달라질 것이다.*/
type Props = {
  modalClose: () => void;
};

function Modalname({ modalClose }: Props) {
  const {
    register,
    watch,
    setValue,
    formState: { errors, isValid },
  } = useForm<{ nickname: string; idCheck: boolean }>({ mode: "onChange" });

  return (
    <MyModal>
      <MyPageModal>
        <ModalH1>닉네임 중복 확인</ModalH1>
        <ModalMargin>
          <FlexDiv>
            <ModalStyledInput
              placeholder="닉네임을 입력해주세요(2~8자)"
              type="nickname"
              id="userNickname"
              required
              {...register("nickname", {
                required: true,
                minLength: 2,
                maxLength: 8,
              })}
            />
            <ModalStyledInputButton>중복확인</ModalStyledInputButton>
          </FlexDiv>
          <ModalErrorDivWrap>
            {errors.nickname?.type === "required" && (
              <ModalErrorDiv>닉네임을 입력해주세요</ModalErrorDiv>
            )}
            {errors.nickname?.type === "minLength" && (
              <ModalErrorDiv>닉네임 길이를 지켜주세요</ModalErrorDiv>
            )}
            {errors.nickname?.type === "maxLength" && (
              <ModalErrorDiv>닉네임 길이를 지켜주세요</ModalErrorDiv>
            )}
          </ModalErrorDivWrap>
        </ModalMargin>
        <ModalMargin>
          <ModalButton onClick={modalClose}>사용하기</ModalButton>
        </ModalMargin>
      </MyPageModal>
    </MyModal>
  );
}

export default Modalname;

모달 창 호출하는 페이지 컴포넌트 구현하기

이렇게 만든 모달 창을 호출하기 위해서는 모달을 여는 state를 호출하였을 때 열리도록 구현을 해야 한다. 그러기 위해서는 먼저 모달을 여는 state를 만들어준다. 그리고 모달창이 열릴때와 닫힐때의 함수를 작성해준다.

❗️Recoil의 방식을 사용하고 있기 때문에 각자 다를 수 있다.

  const [modalOpenName, setmodalOpenName] = useRecoilState(mypageModal);
  const modalNameClick = () => {
    setmodalOpenName(!modalOpenName);
  };
  const modalNameClose = () => {
    setmodalOpenName(!modalOpenName);
  };

이렇게 만들어 준 다음, return문에서 다음과 같이 작성해주면 된다.

  return (
    <div style={{ width: "100%", marginLeft: "20px" }}>
      <CreateStyledInputButton onClick={modalNameClick}>
        변경
      </CreateStyledInputButton>
      {modalOpenName && <Modalname modalClose={modalNameClose} />}
    </div>
  );

완성모습


처음에 모달 창을 만들었을 때는 엄청 헤맸고 그랬지만, 여러 참고자료의 도움 덕분에 어떻게 작성하는지 잘 알게 되었다. 다음에는 라이브러리를 활용한 모달로 alert창을 커스텀 되어있는 모달 팝업창으로 만들 예정이다.🙇‍♂️

📚참고자료
https://curryyou.tistory.com/493
https://velog.io/@sgsg9447/React-Modal-구현

profile
예비 초보 개발자의 프로젝트와 공부 기록일지

0개의 댓글