프로젝트를 하면서 한 가지 바꾸고 싶었던 부분이 있었다. 바로 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-구현