react-modal npm 설치
$ npm install --save react-modal
$ yarn add react-modal
redact-modal의 옵션들
interface Styles {
content?: React.CSSProperties | undefined;
overlay?: React.CSSProperties | undefined;
}
// react-modal Styles 옵션에는 content와 overlay가 있다.
// content : 모달창 내부영역 디자인
// overlay : 모달 외부영역 디자인
interface Props {
isOpen: boolean;
// 모달의 열림을 결정
shouldCloseOnOverlayClick?: boolean | undefined;
// 모달창 바깥을 클릭하면 모달창이 닫히는지 여부, 기본값이 true로 설정
shouldCloseOnEsc?: boolean | undefined;
// esc를 누르면 모달창 닫히는지 여부 , 기본값이 true로 설정
onRequestClose?(event: React.MouseEvent | React.KeyboardEvent): void;
// 모달의 닫힘을 결정
ariaHideApp?: boolean | undefined
// app요소의 숨김을 결정
}
//이 옵션들 외에도 많은 옵션들 있다.
- react-modal을 사용하면 아래와 같은 에러를 볼 수 있다.
Screen Reader 가 react-modal이 열릴 때 사용자가 modal에 집중할 수 있도록 메인 컨텐츠를 읽지 못하도록 숨겨야 하는데 숨기는 대상이 지정되지 않았을 때 발생된다.
이때 ariaHideApp={false}를 사용해서 모달이 열릴 때 최상위 요소를 숨겨주면 에러를 해결할 수 있다.
react-modal 라이브러리를 활용한 모달창 구현 방법
- 공통 모달 만들기
- React-modal을 import 해준 뒤 tsx파일의 return문 안에 모달창 내용을 작성
- react-modal로 공통 모달을 만들고 많은 옵션 들 중에서 isopen, onReqyestClose, style, children 을 props로 넘겨줘서 상위 컴포넌트에서 스타일을 지정하고 데이터를 넣을 수 있게 만든다.
import React from "react";
import Modal from "react-modal";
type ModalProps = {
children?: React.ReactNode;
isopen: boolean;
onRequestClose: () => void;
style: ReactModal.Styles;
};
const CommnModal = ({
children,
isopen,
onRequestClose,
style,
}: ModalProps) => {
return (
<Modal isOpen={isopen}
style={style}
onRequestClose={onRequestClose}
ariaHideApp={false}>
{children}
</Modal>
);
};
export default CommnModal;
//children -> 모달 안에서 사용 될 데이터
//isopen -> 모달의 열림 결정
//onRequestClose -> 모달의 닫힘 결정
//style -> 모달의 overlay와 content 스타일
2. 공통 모달을 사용한 GallerydetailModal 만들기
- GallerydetailModal에서 스타일 지정
- children에 들어갈 내용 및 데이터 작성
import React from "react";
import CommnModal from "shared/ui/commonModal";
import styles from './galleryDetail.module.css'
type GalleryDetailModalProps = {
modalOpen: boolean;
setModalOpen: (isOpen: boolean) => void;
};
const customModalStyles: ReactModal.Styles = {
overlay: {
backgroundColor: " rgba(0, 0, 0, 0.4)",
width: "100%",
height: "100vh",
zIndex: "10",
position: "fixed",
top: "0",
left: "0",
},
content: {
width: "80%",
height: "80%",
zIndex: "11",
position: "absolute",
top: "50%",
left: "50%",
transform: "translate(-50%, -50%)",
borderRadius: "10px",
backgroundColor: "rgba(0, 0, 0, 0.4)",
},
};
const GalleryDetailModal = ({
modalOpen,
setModalOpen,
}: GalleryDetailModalProps) => {
return (
<CommnModal
isopen={modalOpen}
onRequestClose={() => setModalOpen(false)}
style={customModalStyles}
>
<div>테스트1234</div>
</CommnModal>
);
};
export default GalleryDetailModal;
3. 모달이 필요한 컴포넌트에서 GalleryDetailModal 컴포넌트 사용
import React from "react";
import styles from "./galleryCard.module.css";
import { GalleryCardType } from "shared/type/Gallery";
import { useState } from "react";
import GalleryDetailModal from "features/galleryDetailModal/ui";
const GalleryCard = ({ title, imgUrl }: GalleryCardType) => {
const [modalOpen, setModalOpen] = useState(false);
const modalClick = () => {
setModalOpen(true);
};
return (
<div className={styles.container}>
<img
src={imgUrl}
alt="갤러리 이미지"
className={styles.image}
onClick={modalClick}
/>
<div className={styles.title}>{title}</div>
<GalleryDetailModal
modalOpen={modalOpen}
setModalOpen={() => setModalOpen(false)}
/>
</div>
);
};
export default GalleryCard;
'리액트 궁금증' 카테고리의 다른 글
[react-query] 2. react-query의 status (0) | 2024.06.17 |
---|---|
[react-query] 1. react-query와 useQuery알아보기 (0) | 2024.06.17 |
useReducer 다시 찾아볼것 (0) | 2024.02.02 |
React children (0) | 2024.01.18 |
01 10 리액트 props 는 뭘까 (0) | 2024.01.10 |