이전까지 나는 모달을 생성하기 위한 방법으로
주로 CSS 를 선택했었다.
position fixed, relative 설정 후
화면 위에 띄우기 위해 z-index 설정하는 방식
만약 공용모달이 필요할 경우,
prop drilling으로 사용될 컴포넌트에 다 내려주거나,
상태관리 라이브러리를 사용해서
전역으로 state를 관리하는 방식을 사용했었는데,
분명 방법은 많을테니...
다른 방법은 없을까 찾아보다가 Portal 을 찾았다.
https://ko.reactjs.org/docs/portals.html
ReactDom의 Portal 기능은
부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드로
자식을 렌더링 하는 기능을 제공한다.
바깥에 있는 DOM을
DOM 안에 있는 것처럼 연결될 수 있는 포탈을 열어준다는 얘기인데...
이게 무슨 말인지 코드를 통해 보면 쉽다.
먼저 부모 컴포넌트의 DOM 계층 구조 바깥에 있는 DOM 노드
이걸 만들어보면
// public/index.html
<body>
<div id="root"></div>
<div id="modal"></div>
</body>
reactDom.createPortal
실행함수를 만들자.
// Portal.js
import reactDom from "react-dom";
const ModalPortal = ({ children }) => {
const element = document.getElementById("modal");
return reactDom.createPortal(children, element);
};
export default ModalPortal;
Portal 을 사용해서 Modal 생성 준비가 끝났다.
이제 적용해보자
// modal을 사용할 컴포넌트 Main.jsx
import React, { useState } from "react";
import ModalPortal from "../../components/modal/Portal";
import { Modal } from "../../components/modal/Modal";
export const Main = () => {
const [modalOn, setModalOn] = useState(false);
const handleModal = () => {
setModalOn(!modalOn);
};
return (
<div>
<button onClick={handleModal}>열기</button>
<ModalPortal>
{modalOn && <Modal onClose={handleModal} />}
</ModalPortal>
</div>
);
};
구현은 어렵지 않다. 하지만
을 알지 못하고 쓰면 그냥 코드 복붙하는 것 밖에 안된다.
왜 썼는지 모르면서 썼다면 할 줄 모른다고 볼 수 밖에 없다.
공부하라!
데이터바인딩이 단방향으로 이루어지는 React
버블링 막기 위해 stopPropagation을 적용할까 하다가
어떻게 적용 및 실행되는지 SyntheticEvent
에 대해 정리하도록 결정
(리액트에서 이벤트핸들러가 어떻게 작동하는가?)
- e.nativeEvent.stopImmediatePropagation()