-
Notifications
You must be signed in to change notification settings - Fork 4
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
사이드바에 토스트가 가려지던 문제 해결 (feat.createPortal) #841
Conversation
Drawer가 켜진다면 dialog 태그 내에서 생성되고, 닫히거나 열리지 않았다면 toast-content라는 별개의 div에서 생성되도록 구현
⚡️ Lighthouse report!
|
const status = JSON.parse(fetchError.message).status; | ||
if (status === 404) { | ||
return false; | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👍👍👍
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
우스! 해당 부분 저도 어떻게 해야할지 고민이 있었는데, 역시 실행력 갑입니다!
처음에 시도했던 방식이 createRoot로 기존 루트를 2개 만드는 거였는데, css로 처리가 가능하기에 굳이라고 생각되어 하지 않았거든요!
근데 이걸 creatPotal로 만들면서 다이아로그 위에 띄울 다른 방안을 고안하셨군요!!
해당 방법을 하면 개발자 도구에서 어떻게 보이는지 궁금해지네요
(top layer가 2개가 되는걸까요?🤔 아마 그냥 새로운 root가 만들어질 것 같기는 해요.)
아마 이걸로도 탑레이어 위에 쌓이지 않아서 dialog안에 root를 지정해주는 것을 따로 처리해주신 것 같기는 합니다! 혹시 맞을까요?
이번 계기를 통해서 레이어를 어떻게 쌓아 겹겹이 둬야 하는 지에 대해 고민해볼 수 있었습니다 bb
다만, 고민해보고 싶은 부분이 두 가지있습니다.
- drawer에 토스트가 굉장히 깊게 관련되게 되는데 괜찮을까요? 해당 부분이 토스트 해결을 위한 어쩔 수 없는 부분이더라도 완전한 대책은 아니라고 생각이 듭니다. 토스트와 drawer는 독립적인 common으로 작동되는 것이 좋다고 생각이 들어요!
- 현재 뒷 배경의 인터렉션이 가능해서 여러개의 토스트가 발생할 수 있습니다! 근데 이 부분은 기존에 하나의 토스트 리스트로 관리가 되기 때문에 가능한 거였습니다. 이 로직이 3개의 root가 존재하게 되고, 이 root에 각 토스트가 삽입되는 것으로 바뀐 걸로 이해했습니다. 이로 인해 빠르게 한다면 사이드 바에서 즐겨찾기 오류를 발생시키고, 메인페이지에서 다른 알림 등의 오류를 발생시키면 중첩된 토스트가 발생할 것 같은데 혹시 해당 부분은 어떻게 처리되고 있는지 궁금합니다!
제 예상이 틀렸다면 혹시 어떤 이유로 이런 문제가 발생하지 않는지 알려주실 수 있으신가요?? 제가 코드를 잘못 이해했을 수도 있을 것 같아요!
고생하셨습니다 우스!
fe-리뷰완
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
createPortal 을 적용해주셨군요!
예전에 모달 처음 만들 때 createPortal 어떻게 쓸지 고민이 있었는데 Toast 에도 새로운 root를 열어서 사용해볼 수 있군요👍
다만 우스가 Drawer를 라이브러리로 빼낸다고 가정했을때, Toast 관련된 로직은 어떻게 처리하실지 궁금해지더라구요🤔
따라서 저도 수아처럼 우려해본 부분은, 지금 범용적인 컴포넌트인 Toast와 Drawer끼리 로직이 연관되어 있다는 점입니다
이건 좀더 고민해보고 리팩터링해봐야 감이 올거 같아요🤔🤔
setToastList(toastList => [...toastList, { id, text: message }]); | ||
}; | ||
|
||
const setElementId = useCallback((id: ToastContentId) => { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
리렌더링 방지👍👍
drawer랑 toast 분리했습니당 fe-리뷰요청 |
1 similar comment
drawer랑 toast 분리했습니당 fe-리뷰요청 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
코드 잘 읽었습니다.!
똑똑한 우스..
이렇게 설계할 생각 못했는데 대단합니다!
토스트와 모달이 분리가 되면서도 본래 의도는 유지할 수 있어서 좋네요!
다만 코멘트에서 말한 것과 같이 직접 돔을 조작하는 것에 대해서는 한 번 생각해보고 싶습니다!
일단 토스트를 상단에 띄우는 것이 UX적으로 우선이니 머지해도 좋지만
가능하면 직접 돔 조작은 하고 싶지 않은 마음도 있습니다..
추후 수정해도 좋을 것 같아요!
고생하셨어요!
}); | ||
|
||
export default function ToastProvider({ children }: PropsWithChildren) { | ||
const [toastList, setToastList] = useState<ToastInfo[]>([]); | ||
const [toastElementId, setToastElementId] = useState<ToastContentId>('toast-content'); | ||
const toastContentEl = document.getElementById(toastElementId); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
다시 읽으며 든 생각인데, document.getElementById
로 dom을 직접 제어하는 것은 지양된다고 알고 있습니다.
real dom 과 가상돔이 달라지면서 돔 요소를 신뢰할 수 없어진다고 알고 있습니다.
위험부담을 감안하여 진행해야 할까요? 고민이 듭니다!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
이 부분은 잘 모르겠네요.
다만 공식문서에서 있는 방법을 참고하여서 진행했기 때문에 괜찮지 않을까라는 생각이 듭니다
const handleCategoryDrawerClose = () => { | ||
closeCategoryDrawer(); | ||
setElementId('toast-content'); | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
여기까지 오기 위한 빌드업이었군요!
읽으면서 헷갈리는 부분도 있었는데, 이 부분을 읽으니 로직이 확 이해가 갔습니다 👍👍
설계하는 능력이 뛰어나시네요
fe-리뷰완 |
🔥 연관 이슈
close: #738
📝 작업 요약
⏰ 소요 시간
🔎 작업 상세 설명
예시 영상
영상 촬영을 위해 토스트 시간을 10초로 변경하여 찍었습니다. 실제로는 변경 X
2023-11-09.12.34.18.mov
참고 자료
shadcn-ui/ui#75 (힌트를 얻은 사이트)
https://react-ko.dev/reference/react-dom/createPortal (리엑트 공식문서)
https://tanstack.com/query/v4/docs/react/guides/mutations ( 공식문서 mutate에서 async/await을 안붙이더라구요)