리액트 프로젝트는 기본적으로 index.js에서 렌더링한다.
import React from "react";
import ReactDOM from "react-dom/client";
import App from "./App";
const root = ReactDOM.createRoot(document.getElementById("root"));
root.render(
<React.StrictMode>
<Router>
**<App />**
</Router>
</React.StrictMode>,
);
reactDOM 라이브러리가 제공하는 reactRoot 함수가 반환하는 render 함수를 이용하는데, createRoot 함수는 인자로 먼저 document.getElementById(”root”)
를 받는다.
여기서 id가 root인 HTML 요소는 public/index.html
에 있다.
아래 html 파일이 개발서버를 구동했을 때 화면에 보이게 되는 html 파일이라고 볼 수 있다.
public/index.html
<!DOCTYPE html>
<html lang="en">
<head>
...
</head>
<body>
<div id="root"></div>
**<div id="modal"></div>**
</body>
</html>
root 페이지와 분리해서 만들기 위해 id=”modal”
를 index.html에 만들어 뒀다.

CreatePortal 이란?
자식들을 DOM의 다른 부분으로 렌더링해주는 기능을 제공해준다.
https://xionwcfm.tistory.com/316#google_vignette
src/components/Modal/ModalContainer.jsx
import { createPortal } from "react-dom";
function ModalContainer({ children }) {
return createPortal(<>{children}</>, document.getElementById("modal"));
}
export default ModalContainer;
createPortal(children, domNode, key?)
- 첫번째 인자: domNode의 children이 될 컴포넌트 혹은 jsx가 들어간다
- 두번째 인자: children의 부모가 될 domNode를 넣어준다. index.html에
<div id="modal"></div>
를 미리 만들어 뒀다. - 세번째 인자: 옵션인 키. 포털의 키로 고유한 문자열이나 숫자가 들어간다.
- JSX에 포함될 수 있는 것이나 리액트 컴포넌트로 반환될 수 있는 React 노드를 반환한다.
- 그래서 리액트가 렌더링 output에서 이를 발견하면 domNode안의 children을 출력한다!
src/components/Modal/index.jsx
import { useEffect } from "react";
import { useRef } from "react";
import styled from "styled-components";
import useOutsideClick from "hooks/useOutSideClick";
import ModalContainer from "./ModalContainer";
function Modal({ onClose, children }) {
const modalRef = useRef(null);
const handleClose = () => {
onClose?.();
};
return (
<ModalContainer>
<Overlay>
<ModalWrap ref={modalRef}>
<Contents>{children}</Contents>
</ModalWrap>
</Overlay>
</ModalContainer>
);
}
export default Modal;
모달 닫고 끄는 로직은 useState를 이용!
state가 true일 땐 모달을 보여주고, false일 땐 모달을 보여주지 않는다.
HelpIcon과 눈에 띄는 색깔로 모달을 띄워 줄 글자(LRAT)를 강조하고, 사용자가 글자를 클릭하면 모달이 열린다.
→ LratModal.jsx가 랜딩된다
src/pages/Intro/MethodArea.jsx
import LratModal from "./LratModal";
function MethodArea() {
const [isOpen, setIsOpen] = useState(false);
const onOpen = () => {
setIsOpen(true);
};
const onClose = () => {
setIsOpen(false);
};
return (
<Container>
<SubTitle content="데이터 분석 방법" />
<SubDesc>
<span onClick={onOpen}>
<HelpIcon /> LRAT (Lifestyle and Routine Activity Theories)
</span>
의 세 가지 요소를 개념화(operationalization)했습니다.
</SubDesc>
...
{isOpen && <LratModal onClose={onClose} />}
</Container>
);
}
export default MethodArea;
components 폴더에 만들어 둔 Modal을 import해서 모달 내용을 채운다.
‘확인’ 버튼이나 ‘X’ 아이콘을 클릭하면 모달이 닫힌다.
src/pages/Intro/LratModal.jsx
import styled from "styled-components";
import { Modal } from "components";
import { modalTree } from "assets/img";
import { MdClose } from "react-icons/md";
function LratModal({ onClose }) {
return (
<Modal onClose={onClose}>
<CloseBtn onClick={onClose} />
<Content>
...
</Content>
<Button onClick={onClose}>
<p align="center">확인</p>
</Button>
</Modal>
);
}
export default LratModal;
'프로젝트 > 졸업 프로젝트' 카테고리의 다른 글
Throttle로 스크롤 감지하고 스크롤하면 Header css 바꾸기 (1) | 2024.04.18 |
---|---|
보충 설명이 필요한 내용은 Modal을 사용해서 UX를 높임 (1) | 2024.04.18 |
가상 엘리먼트 ::before ::after (0) | 2024.04.18 |