// FaRegTrashAlt: react-icons 라이브러리에서 가져온 휴지통 아이콘 컴포넌트
import { FaRegTrashAlt } from "react-icons/fa";
// Modal: 현재 디렉토리의 components 폴더에서 가져온 모달 컴포넌트
import Modal from "./components/Modal";
function App() {
return (
<>
{/* 버튼 생성하고 휴지통 아이콘과 함께 '삭제하기' 텍스트를 표시 */}
<button>
<FaRegTrashAlt /> {/* 휴지통 아이콘 */}
삭제하기 {/* 버튼의 텍스트 */}
</button>
<Modal /> {/* Modal 컴포넌트를 추가 */}
</>
);
}
// App 컴포넌트를 기본 내보내기 하여 다른 파일에서 불러올 수 있게함
export default App;
// IoClose: react-icons 라이브러리에서 가져온 'X' (닫기) 아이콘 컴포넌트
import { IoClose } from "react-icons/io5";
// 'Modal' 컴포넌트를 정의
// 이 컴포넌트는 모달 창을 나타내며, 다음의 props를 받음 :
// 'isOpen' - 모달 창이 열려 있는지 여부를 결정하는 값
// 'onClose' - 모달 창을 닫는 기능을 제공하는 함수
// 'children' - 모달 창 안에 표시될 내용
const Modal = ({ isOpen, onClose, children }) => {
return (
// 모달 창 뜰 때 화면을 어둡게 하는 오버레이 역할의 div
<div className="modal-overlay">
{/* 모달 창 자체를 나타내는 div */}
<div className="modal">
{/* 모달 창 닫기 버튼, IoClose 아이콘이 버튼에 들어감 */}
<button className="modal-close">
<IoClose /> {/* X 아이콘 */}
</button>
{/* children은 모달 창 안에 삽입할 추가적인 내용을 렌더링 */}
{children}
</div>
</div>
);
};
// Modal 컴포넌트를 기본 내보내기 하여 다른 파일에서 불러올 수 있게함
export default Modal;
모달 열려있는지 여부 나타내는 'isOpen', 모달 닫는 'onClose',
모달 안에 들어갈 내용 작성할 'children'➡이 세가지 props를 받음
'children'➡컴포넌트 재사용하기 위해 내용을 prop으로 전달하는데
모달 컴포넌트 안에서 모든 내용 다 작성하면 위처럼
삭제하기 기능이 아닌 다른 곳에서 모달 컴포넌트 사용할 때
재사용 어렵기에 동적으로 컨텐츠 전달하는 역할을 함
/* .modal-overlay: 화면 전체를 덮는 반투명한 검은색 오버레이 */
.modal-overlay {
position: fixed; /* 화면 스크롤과 상관없이 고정 위치에 표시 */
top: 0; /* 화면의 맨 위에 맞춤 */
left: 0; /* 화면의 왼쪽에 맞춤 */
width: 100%; /* 화면의 너비 전체를 덮음 */
height: 100%; /* 화면의 높이 전체를 덮음 */
background: rgba(0, 0, 0, 0.5); /* 반투명한 검은색 배경 */
display: flex; /* 모달을 가운데 정렬하기 위해 flexbox 사용 */
justify-content: center; /* 수평 가운데 정렬 */
align-items: center; /* 수직 가운데 정렬 */
}
/* .modal: 오버레이 위에 표시되는 흰색 모달 창 */
.modal {
background: white; /* 모달 배경을 흰색으로 설정 */
border-radius: 8px; /* 모달 모서리를 둥글게 만듦 */
box-shadow: inset; /* 모달 안쪽에 그림자를 추가해 입체감 부여 */
padding: 20px; /* 모달 내부 여백 추가 */
position: relative; /* 닫기 버튼 위치를 잡기 위해 상대적 위치 설정 */
}
/* .modal-close: 모달 창의 닫기 버튼 스타일 */
.modal-close {
position: absolute; /* 모달 내에서 절대적 위치 설정 */
width: 20px; /* 닫기 버튼 너비 */
height: 20px; /* 닫기 버튼 높이 */
right: 5px; /* 모달 창의 오른쪽에서 5px 떨어진 위치에 배치 */
top: 5px; /* 모달 창의 위쪽에서 5px 떨어진 위치에 배치 */
}
// App 컴포넌트 정의 파일
// 'FaRegTrashAlt'와 'Modal' 컴포넌트를 불러오고
// 상태 관리를 위해 useState 훅 사용
import { FaRegTrashAlt } from "react-icons/fa";
import Modal from "./components/Modal";
import { useState } from "react";
function App() {
// 모달 창의 열림/닫힘 상태를 관리하는 상태 변수 'open'과
// 이를 업데이트하는 함수 'setOpen'을 useState로 설정
const [open, setOpen] = useState(false);
return (
<>
{/* '삭제하기' 버튼 클릭하면 'open' 상태를 true로 설정하여 모달 창 열음 */}
<button onClick={() => setOpen(true)}>
<FaRegTrashAlt /> {/* 휴지통 아이콘 */}
삭제하기 {/* 버튼의 텍스트 */}
</button>
{/* Modal 컴포넌트를 표시, 'isOpen' prop에 'open' 상태 값을 전달하고,
'onClose' prop에 모달을 닫는 함수를 전달 */}
<Modal isOpen={open} onClose={() => setOpen(false)}>
{/* children - Modal 컴포넌트에 표시될 내용 */}
<div>
{/* 삭제 확인 메시지 */}
<p>이 항목을 삭제하시겠습니까?</p>
<div>
{/* 삭제 버튼 - 여기에 실제 삭제 기능을 연결할 수 있음 */}
<button>삭제</button>
{/* 취소 버튼 - 클릭 시 'open' 상태를 false로 설정하여 모달 창을 닫음 */}
<button onClick={() => setOpen(false)}>
취소
</button>
</div>
</div>
</Modal>
</>
);
}
// App 컴포넌트를 기본 내보내기 하여 다른 파일에서 불러올 수 있게함
export default App;
setOpen을 false➡true로 설정하면 모달 열 수 있기에
삭제하기 버튼 클릭하면 setOpen(true) 호출해서 상태를 업데이트 하도록 함
또한 Modal 컴포넌트에서도 사용할 수 있도록 상태와 이벤트 전달하기
const Modal = ({ isOpen, onClose, children }) => {
// 만약 isOpen이 false이면 null 반환하여 모달을 렌더링하지 않음
if (!isOpen) return null;
return (
<div onClick={onClose} className="modal-overlay">
<div onClick={(e) => e.stopPropagation()} className="modal">
<button onClick={onClose} className="modal-close">
<IoClose />
</button>
{children}
</div>
</div>
);
};
Modal 컴포넌트에선 isOpen이 false,
닫힌 상태면 null 반환해서 모달이 화면에 나타나지 않도록 함
열려있는 모달창 닫기 위해 닫기 버튼 클릭하면
onClose가 호출 되어 모달을 닫을 수 있음