모달에 대한 뭔가 알수없는 공포(?)가 있었다 ㅋㅋ
이번에 쉬운 예제로써 한번 경험해보고 어렵지 않다는걸 알았다
초보분들도 이해할 수 있게 참고할 수 있게 정리해보기
우선, 예제 연습 시작 전에 간단히 개념을 짚고
모달에서 어떤것이 중요한지 알고 넘어가기 🐰
1. 모달이란? (원리부터 이해하기)
모달은 화면 위에 덮어씌우는 작은 창!
- 보통 배경은 어둡게 흐리게(반투명) 만들고,
- 중앙에 내용이 팝업처럼 뜨지.
사용자가 모달 안의 작업을 하거나 확인을 하면 모달이 닫혀.
그래서 모달이 뜨고 안 뜨는 상태를 관리하는 게 중요해.
2. 모달 동작 원리
- 모달을 보여줄지 말지를 결정하는 상태(state) 가 필요해.
- 상태가 true면 모달 보이고, false면 모달 숨김.
- 버튼 같은 걸 누르면 상태가 바뀌면서 모달이 열리고 닫히는 것!
3. 리액트에서 모달 만들기 (기본 구조)
import React, { useState } from "react";
export default function App() {
// 모달 열림 여부 상태
const [isModalOpen, setIsModalOpen] = useState(false);
// 모달 열기 함수
const openModal = () => setIsModalOpen(true);
// 모달 닫기 함수
const closeModal = () => setIsModalOpen(false);
return (
<div>
<button onClick={openModal}>모달 열기</button>
{/* 모달 상태가 true일 때만 모달 보여주기 */}
{isModalOpen && (
<div className="modal-backdrop" onClick={closeModal}>
{/* onClick은 배경 클릭 시 모달 닫기 */}
<div className="modal-content" onClick={e => e.stopPropagation()}>
{/* 모달 안 내용 - 클릭해도 닫히지 않게 막기 */}
<h2>모달 제목</h2>
<p>여기에 모달 내용이 들어갑니다.</p>
<button onClick={closeModal}>닫기</button>
</div>
</div>
)}
</div>
);
}
4. 모달 디자인 어디서 하나?
- 위 코드의 .modal-backdrop 과 .modal-content 를 CSS로 꾸미면 돼!
- 보통 이렇게 스타일 줘:
.modal-backdrop {
position: fixed; /* 화면 고정 */
top: 0; left: 0; right: 0; bottom: 0;
background-color: rgba(0,0,0,0.5); /* 검은색 반투명 배경 */
display: flex;
justify-content: center;
align-items: center;
z-index: 999; /* 가장 위에 오도록 */
}
.modal-content {
background: white;
padding: 20px;
border-radius: 8px;
min-width: 300px;
}
5. 정리
- 모달이란? 화면 위에 띄우는 작은 팝업창.
- 모달의 열림/닫힘 상태를 useState로 관리한다.
- 모달이 열려 있으면 배경과 내용 컴포넌트를 화면에 렌더링한다.
- 배경 클릭하거나 닫기 버튼 누르면 상태를 바꿔 모달 닫는다.
- 디자인은 CSS로 배경 반투명, 내용은 흰색 박스 등 꾸민다.
6. 타입스크립트 적용 팁
- 컴포넌트 props에 타입 지정하기
- 예를 들어, 모달 컴포넌트를 따로 만들면:
type ModalProps = {
onClose: () => void;
children: React.ReactNode;
};
export function Modal({ onClose, children }: ModalProps) {
return (
<div className="modal-backdrop" onClick={onClose}>
<div className="modal-content" onClick={e => e.stopPropagation()}>
{children}
<button onClick={onClose}>닫기</button>
</div>
</div>
);
}
이렇게 하면 재사용성도 좋아!
우선 이렇게, 모달을 만들 때는 상태가 필수인걸로 알게 됐다.♥︎
이제, 실제로 연습해볼 예제 목표는
💡 예제 목표
✓버튼 클릭 → 모달 열림
✓모달 안에 간단한 메시지랑 닫기 버튼
그러면 예제 구현 목표에 맞게 ..! 코드를 작성해보자
해당 연습 예제는, 모달 컴포넌트를 따로 분리한 것
우선 전체 코드는 다음과 같다.
import React, { useState } from "react";
function SimpleModal({ onClose }) {
return (
<div
style={{
position: "fixed",
top: 0, left: 0, right: 0, bottom: 0,
backgroundColor: "rgba(0,0,0,0.3)",
display: "flex", justifyContent: "center", alignItems: "center",
}}
>
<div style={{ backgroundColor: "white", padding: 30, borderRadius: 10 }}>
<h2>안녕하세요! 👋</h2>
<p>이건 연습용 모달입니다.</p>
<button onClick={onClose}>닫기</button>
</div>
</div>
);
}
export default function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<div>
<h1>모달 연습 페이지</h1>
<button onClick={() => setIsModalOpen(true)}>모달 열기</button>
{isModalOpen && <SimpleModal onClose={() => setIsModalOpen(false)} />}
</div>
);
}
모달에서는 상태가 필수 ⭐️
상태로써, 모달을 열고 닫는게 필요하기 때문이다.
function SimpleModal({ onClose }) {
return (
<div
style={{
position: "fixed",
top: 0, left: 0, right: 0, bottom: 0,
backgroundColor: "rgba(0,0,0,0.3)",
display: "flex", justifyContent: "center", alignItems: "center",
}}
>
<div style={{ backgroundColor: "white", padding: 30, borderRadius: 10 }}>
<h2>안녕하세요! 👋</h2>
<p>이건 연습용 모달입니다.</p>
<button onClick={onClose}>닫기</button>
</div>
</div>
);
}
해당 코드를 설명해보자면,
✏️ SimpleModal이라는 모달 컴포넌트를 만들었다.
→ 이 컴포넌트는 자식 컴포넌트로써 App. 부모 컴포넌트에서 사용 된다.
난 항상 Props 때문에 이 부모 > 자식 흐름이 어려운데,
여기서도 SimpleModal이 코드 작성 된 흐름 상, 위에 있기 때문에
뭔가 또 느낌이 이 컴포넌트가 부모인 느낌이라, 프롭스를 내려주는게 종종 헷갈린다.
아무튼, 이렇게 재사용될 SimpleModal 컴포넌트를 먼저 미리 만들어줬다.
여기서, 버튼의 OnClick, onClose 이 부분이 조금 헷갈릴테지만 잠시만 넘어가보고 app부터 보자!
export default function App() {
const [isModalOpen, setIsModalOpen] = useState(false);
return (
<div>
<h1>모달 연습 페이지</h1>
<button onClick={() => setIsModalOpen(true)}>모달 열기</button>
{isModalOpen && <SimpleModal onClose={() => setIsModalOpen(false)} />}
</div>
);
}
✏️ 버튼을 눌러, 모달을 키고, 끄기 위해서 상태를 먼저 만들어줬다.
isModalOpen이 true일 경우, 모달이 보이게. false일 경우 꺼지게.
초기값은 꺼진 상태로써 false를 준 것!
<button onClick={() => setIsModalOpen(true)}>모달 열기</button>
버튼을 누르면, onClick 함수가 실행된다.
이 함수는 setIsModalOpen함수를 true로 바꿔준다.
그 때, 이 isModalOpen이 true가 되고,
true가 됐을 때. <SimpleModal> 컴포넌트가 등장하는 것!
{isModalOpen && <SimpleModal onClose={() => setIsModalOpen(false)} />}
..
..
이까진 이해가 쉬운데, 여기서 onClose 부분은 뭘까 ! ?
이 부분은,
onClose 라는 함수를 내려주는 것. 자식에게!
이 onClose 함수는.. 상태를 false로 바꿔주는 거다.
onClose는 어떤 역할?
모달을 닫는 함수
- 모달을 닫으려면 setIsModalOpen(false)를 실행해야 하는데
- 근데 모달 컴포넌트 안에서는 직접적으로 setIsModalOpen에 접근할 수 없다.
- 그래서 부모 컴포넌트(App) 가 만든 setIsModalOpen(false)를 함수로 만들어서 props로 내려준다.
자식 컴포넌트(SimpleModal)
function SimpleModal({ onClose }) {
...
<button onClick={onClose}>닫기</button>
...
}
- 모달 내부에서 "닫기" 버튼 클릭 → onClose() 실행
- 결과적으로 setIsModalOpen(false)가 실행 → 모달이 닫힘
그래서 다시 모달 컴포넌트로 넘어가면,
부모app에서 넘겨받은 onClose함수를 내려받아서,
function SimpleModal({ onClose }) {
return (
<div
style={{
position: "fixed",
top: 0, left: 0, right: 0, bottom: 0,
backgroundColor: "rgba(0,0,0,0.3)",
display: "flex", justifyContent: "center", alignItems: "center",
}}
>
<div style={{ backgroundColor: "white", padding: 30, borderRadius: 10 }}>
<h2>안녕하세요! 👋</h2>
<p>이건 연습용 모달입니다.</p>
<button onClick={onClose}>닫기</button> //여기!!!
</div>
</div>
);
}
상태를 false로 바꾸는 함수를 여기서 사용할 수 있는 것 !
기능적인 부분은 이렇다.
디자인 적 요소를 살펴본다면
function SimpleModal({ onClose }) {
return (
<div
style={{
position: "fixed",
top: 0, left: 0, right: 0, bottom: 0,
backgroundColor: "rgba(0,0,0,0.3)",
display: "flex", justifyContent: "center", alignItems: "center",
}}
>
여기서 이 div가 모달 배경이 되는거다.
그러니까, 상태가 true로 바뀌어서 모달 보여줘! 하면
function SimpleModal({ onClose }) {
return (
<div
style={{
position: "fixed",
top: 0, left: 0, right: 0, bottom: 0,
backgroundColor: "rgba(0,0,0,0.3)",
display: "flex", justifyContent: "center", alignItems: "center",
}}
>
<div style={{ backgroundColor: "white", padding: 30, borderRadius: 10 }}>
<h2>안녕하세요! 👋</h2>
<p>이건 연습용 모달입니다.</p>
<button onClick={onClose}>닫기</button>
</div>
</div>
);
}
이 모달 컴포넌트가 짜란~ 하고 나타나는건데
배경은 저렇게 div로 살짝 불투명한거고,
그 위에 이제 모달이 안녕~ 하고 나타나는 것!🐰🤍
정말 어렵지 않게 구현할 수 있었다.
쉬운 예제부터 하나씩 쳐보는게 중요한 것 같다.
'Studying > React' 카테고리의 다른 글
리액트 공부하기 - hook-form 훅폼 사용시 disabled 지정해야할까? 고민 (1) | 2025.07.02 |
---|---|
리액트 공부하기 - 상태 useState에서, setter 를 Props로 내려주기, 타입 지정하기 (부모 컴포넌트에서, 자식 컴포넌트로 상태를 props로 전달할 경우) (1) | 2025.07.01 |
리액트 공부하기 - hook form (0) | 2025.06.24 |
리액트 - input은 문자열 (1) | 2025.06.24 |
리액트 타입스크립트 공부하기 - 유효성 검사 react-hook-form 으로 라이브러리 사용해서 검사하기 (0) | 2025.06.23 |