1. 문제의 발단
- 스타일 가이드를 고치면서 확인하니, z-index가 모든 alert, modal등에서 꼬여있다.
- 가장 최상의 단위를 잡고, 위계를 생각하며 기획이 되어야 하지만 추가되는 사항이 많고, 리팩토링 하지 못 해서 꼬여있었다.
- 그래서 임시로 추가할 alert에 z-index를 9999로 설정하고 만들었다.
- 하지만 하위 노드에서 이미 modal을 만들고, 그것을 기준으로 다음 컴포넌트들을 만들어 z-index와 상관없이 최상위로 올라오지 않는 이슈가 있었다.
- 그래서 아예 처음부터 가장 최상위에 올려서 렌더링 하기로 하였다.
2. Potal?
- 지정한 DOM의 외부에 렌더링을 하게 만들어주는 함수
- 첫 번째 인자에는 컴포넌트, 두 번째 인자로 DOM을 넣어준다.
3. 예시
import { Dispatch, SetStateAction, useEffect } from 'react';
import { createPortal } from 'react-dom';
export function Alert({
children,
setState,
}: {
children: React.ReactNode;
setState: Dispatch<SetStateAction<boolean>>;
}) {
// useEffect로 timeout을 걸어 3초 뒤 자동으로 꺼지게 만든다.
useEffect(() => {
const timeout = setTimeout(() => {
setState(false);
}, 3000);
// 다시 alert가 열리더라도, 처음 timeout을 초기화 하여 가장 나중에 열린 alert를 3초 유지시킨다.
return () => clearTimeout(timeout);
}, []);
// 가장 최상위 DOM을 선택한다.
const modalRoot = document.getElementById('modal-root');
// createPortal로 return한다.
return createPortal(
<Backdrop onClick={() => setState(false)}>
<div onClick={(e) => e.stopPropagation()}>
{children}
</div>
</Backdrop>,
modalRoot!
) as any;
}
4. 소감
- 처음 스타일 가이드를 잡을때, z-index도 따로 설정에 잡아 놓는 것이 가장 좋겠다.
- 예를 들어, 항상 최상위에 오는 Backdrop을 최상위, 그 아래로 header, footer 등으로 말이다.
- 그리고 상수로 z-index를 관리하면 중간에 다른 단계를 넣거나 수정하더라도 편하게 사용할 수 있다.
'Coding > Today I Learned' 카테고리의 다른 글
2023.08.11(Fri.) <Atomic Design Pattern> (0) | 2023.08.12 |
---|---|
2023.07.27(Tue.) <얻은 알고리즘 문제 : 해싱, 시간파싱> (0) | 2023.07.27 |
2023.06.29(Tue.) <Blob Type Response의 에러 처리> (0) | 2023.06.29 |
2023.06.26(Mon.) <UX/UI 아티클 정리> (0) | 2023.06.26 |
2023.06.23(Fri.) <노션 주간 업무 보고 템플릿 공유> (0) | 2023.06.23 |