끄적끄적

React Hooks) 나만의 custom modal창 만들기 본문

React

React Hooks) 나만의 custom modal창 만들기

2022. 10. 29. 04:27


현재 많은 라이브러리들이 제공하는 Modal창들이 있지만, 각각 생긴것 들이 모두 다르고, api가 달라 여러개를 동시에 쓰기가 쉽지 않습니다.
또한 react를 잘 이용하는 느낌으로 사용하기 위해 나만의 모달창을 하나 만들어 보겠습니다.
느낌새는 ant design의 모달과 약간 유사하게 제작을 해보았지만, 커스텀을 통해 어느정도의 수정이 가능하도록 해보겠습니다.


가장먼저 모달 컴포넌트의 본체를 만들겠습니다.
1. MyModal.js

import React from 'react';
import styles from './MyModal.module.css';

export default function MyModal({ open, title, bodyStyle, children, onCancel, footer, width}) {

	// open: boolean
    // title: string
    // bodyStyle: CSS Propery (Object)
    // onCancel: func
    // footer: ReactNode (Array)

    return (
        <div 
            className={open ? styles.root : styles.rootDisable}
        >
            <div 
                className={styles.modalContainer}
                style={{ 
                    width: width ? width : ''
                }}
            >
                <div 
                    className={styles.close} 
                    onClick={onCancel}
                >
                    ×
                </div>

                {
                    title ?
                        <p className={styles.title}>{title}</p>
                        :
                        null
                }

                <div className={styles.modalBody} style={bodyStyle}>
                    {children}
                </div>


                {
                    footer.length > 0 ?
                        <div className={styles.footer}>
                            {footer.map(d => d)}
                        </div>
                        :
                        null
                }

            </div>
        </div>
    )
}

여기서 css파일 구조는, CSS Module로 진행을 하였습니다.
2. MyModal.module.css

.root{
    position: fixed;
    top: 0;
    left: 0;
    z-index: 100;
    width: 100vw;
    height: 100vh;
    background-color: rgb(202, 202, 202,0.6);
}
.rootDisable{
    display: none;
}
.modalContainer{
    width: 500px;
    position: absolute;
    z-index: 101;
    top: 30%;
    left: 50%;
    transform: translate(-50%, -50%);
    background-color: white;
    border-radius: 5px;
}
.close{
    position: absolute;
    top: 3px;
    right: 15px;
    font-size: 26px;
}
.close:hover{cursor: pointer;}
.title{
    width: 95%;
    height: 50px;
    line-height: 50px;
    vertical-align: middle;
    padding: 0 10px;
    border-bottom: 1px solid #DFDFDF;
    margin-left: auto;
    margin-right: auto;
}
.modalBody{
    padding: 10px 20px;
}
.footer{
    width: 100%;
    height: 50px;
    padding: 10px;
    display: flex;
    justify-content: center;
}
.footer button{
    width: 60px;
    height: 30px;
    line-height: 30px;
    margin-left: 10px;
    margin-right: 10px;
    background-color: #C8C9FF;
    border: none;
    outline: 0;
    border-radius: 3px;
    color: rgb(56, 56, 63);
}
.footer button:hover{
    background-color: #bdbeee;
}



이제 컴포넌트는 완성이 되었습니다.
그럼 본문에서 모달창을 열고 요소들을 넘겨주는 걸 보겠습니다.

import React, {useState} from 'react';
import MyModal from './MyModal';

function App(){

	const [modalOpen, setModalOpen] = useState(false);
    
    return(
    	<>
            // ...
            <button onClick={e => setModalOpen(true)>모달열기</button>
            // ...
            
            
            <MyModal
            	open={modalOpen}
                width={500}
                title="나의모달제목"
                onCancel={e => setModalOpen(false)}
                footer={[
                        <button onClick={e => setOpen(false)}>확인</button>,
                        <button onClick={e => setOpen(false)}>취소</button>
                        ]}
            >
            	나의 모달 컨텐츠
                <p>hello</p>
            </MyModal>
        </>
    )
}

export default App;



이제 버튼을 눌러 모달을 열어봅시다.

성공적으로 내가 원하는 모달이 나왔습니다!










'React' 카테고리의 다른 글

NextJS) Next.JS 왜쓸까?  (0) 2023.07.19
NextJS) v12 to v13 버전 업데이트하기  (0) 2023.02.01
[React] 함수형 setState  (0) 2022.02.28
NextJS웹사이트에 PWA적용하기  (0) 2022.02.05
React Key값 index로 사용해도 될까?  (0) 2021.09.30
Comments