Repository navigation
[FIX] 모달 스택 z-index가 닫을 때 반납되지 않는 문제 - #322
Conversation
- 모달 스택 인덱스를 세는 카운터가 증가만 하고 반납되지 않아, 중첩되지 않은 단일 모달도 세션이 길어질수록 더 큰 z-index를 받던 문제를 고쳤습니다 - modal-stack-registry에 releaseModalStackIndex를 추가하고, Modal이 닫히거나 언마운트될 때 반납하도록 했습니다 - Modal의 open()이 이미 열린 상태에서 중복 호출돼도 다시 acquire하지 않도록 가드를 추가했습니다 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
- OverlayModal이 acquireModalStackIndex만 쓰고 반납하지 않던 걸 고쳤습니다 - isOpen이 아니라 shouldRender(퇴장 애니메이션이 끝나 실제로 사라지는 시점)에 맞춰 반납해서, 닫히는 중인 모달과 그사이 새로 열리는 모달이 같은 인덱스를 공유하지 않도록 했습니다 Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
|
Warning Review limit reachedThis review ran on the open-source allowance, not this organization's plan, because the pull request author doesn't have an assigned seat. Waiting won't change this — ask an organization admin to assign them a seat, or add seats in Billing if every seat is already assigned, then retry. Next included review available in 53 minutes. View limit details
Comment |
Timo Performance ReportBundle Size — timo-web
Lighthouse — timo-web
Image Optimization — timo-web
측정 커밋: |
ehye1
left a comment
There was a problem hiding this comment.
와우 이런 문제는 어떻게 찾으셨나요? 덕분에 z-index에 대해서 더 배우게 됐습니다. 굿굿
코드리뷰 하다가 엣지 케이스를 발견했어요..😢 앱잼 때 제가 급하게 작성하느라 미처 확인하지 못했던 부분이더라고요. |
…to fix/ui/320-release-modal-stack-index # Conflicts: # packages/timo-design-system/src/components/layout/modal/Modal.tsx
There was a problem hiding this comment.
이번 PR 보면서 정말 많이 배웠어요…! 저는 모달이 잘 뜨고 닫히는지만 확인해서, 내부적으로 z-index 값이 계속 증가하고 있다는 건 미처 생각하지 못했던 것 같아요. 개발자 도구로 직접 확인해 보니까 수정 전에는 계속 올라가던 값이 수정 후에는 50으로 유지돼서 신기했어요!! 👀
궁금해서 더 공부해 봤는데 이렇게 값이 계속 누적되면 쌓임 맥락에 따라 고정된 z-index를 쓰는 토스트까지 가릴 수 있다고 하더라고요. 눈에 보이는 화면뿐 아니라 내부 값이 반복 사용하면서 어떻게 변하고 다른 요소에 어떤 영향을 주는지도 고려해야 한다는 걸 배웠습니다!! 👍👍💕
ISSUE 🔗
close #320
What is this PR? 🔍
모달 스택 깊이를 세는 카운터가 모달이 닫혀도 반납되지 않던 문제를 고쳤습니다.
Modal과OverlayModal양쪽에 반납 로직을 추가하고, 중복 open 호출에 대한 가드도 더했습니다.배경
Modal·OverlayModal이 모달을 열 때마다acquireModalStackIndex()로 번호를 받아 z-index(BASE + index * STEP)를 계산했는데, 이 번호를 닫을 때 반납하는 코드가 없었습니다.nextModalStackIndex가 세션 내내 증가만 해서, 전혀 중첩되지 않은 단일 모달도 모달을 여러 번 열었다 닫았다 하면 점점 더 큰 z-index를 받았습니다. 공용AnimatedToast처럼z-50고정값을 쓰는 다른 요소가 "모달은 대략 50 근처"라고 가정하고 있어서, 세션이 길어지면 그 가정이 깨질 수 있었습니다.modal-stack-registry / Modal
releaseModalStackIndex를 추가하고,Modal이 닫히거나(버튼, Escape, 바깥 클릭 등 어떤 경로든) 언마운트될 때 호출하도록 했습니다.open()이 이미 열린 상태에서 중복 호출돼도 다시 acquire하지 않도록 가드도 추가했습니다.open()이 가드 없이 매번 acquire하는데, 이미 열린 상태에서 또 호출되면(같은 값으로setIsOpen(true)를 또 부르는 경우) React가 리렌더를 건너뛰어서 release를 맡은 effect가 다시 등록되지 않습니다. 그러면 모달이 완전히 닫혀도 카운트가 남습니다.useEffect(() => { if (!isOpen) return; return () => releaseModalStackIndex(); }, [isOpen])로 acquire와 release를 짝지었습니다. React StrictMode의 effect 이중 실행은 "새로 마운트되는 커밋"에만 적용되는데, 이 컴포넌트는 항상isOpen=false로 마운트된 뒤 나중에 열리므로 이중 실행과 겹치지 않는다는 걸 React 소스(recursivelyTraverseAndDoubleInvokeEffectsInDEV, Placement 플래그 기준 분기)로 확인했습니다.OverlayModal
OverlayModal은 닫힌 뒤에도 200ms 퇴장 애니메이션(shouldRender)이 끝날 때까지 화면에 남아 있습니다.isOpen이 아니라shouldRender에 맞춰 반납합니다.isOpen기준으로 하면 페이드아웃 중인 모달이 아직 쓰고 있는 z-index를 그사이 새로 열리는 모달이 받아갈 수 있어서, 애니메이션이 완전히 끝나는 시점에 반납하도록 했습니다.Modal처럼open()류의 중복 호출 가드는 이 컴포넌트엔 해당 사항이 없습니다(isOpen을 부모가 prop으로 제어하는 구조라, 값이 안 바뀌면 애초에 effect가 다시 안 돕니다).To Reviewers
Screenshot 📷
Test Checklist ✔
pnpm check-types(apps/timo-web,packages/timo-design-system) 통과pnpm lint(ESLint, 변경 범위) 통과pnpm prettier --check(변경 범위) 통과