https://github.com/NEARworld/gamercade-site/commit/66b6e899df4e3b0ce185336a3b42df49e8e6f66c
function Modal({modalStatus}: Props) {
const [topDistance, setTopDistance] = useState(window.scrollY);
function handleScroll() {
setTopDistance(window.scrollY);
}
useEffect(() => {
window.addEventListener('scroll', handleScroll);
return () => {
window.removeEventListener('scroll', handleScroll);
}
}, [])
const card = cards.find((item) => item.id === modalStatus.id)
return <Wrapper>
<ModalBody onMouseDown={(e) => {
e.nativeEvent.stopImmediatePropagation()}
}
topDistance={topDistance}
>
{card ?
<Title>{card.name}</Title>
: null}
</ModalBody>
</Wrapper>
}
export default Modal;
window.scrollY
를 상태 값으로 만들어 사용.
useEffect
에
window.addEventListener('scroll', callback)
위 이벤트리스너를 추가.
{modalStatus.isOpen ? <Modal modalStatus={modalStatus} /> : ''}
Modal
컴포넌트는 위의 코드 부분에서 언마운트되었다가 마운트되기를 반복하도록 설계되어 있으므로 addEventListener
가 누적되는 것을 막기 위해 useEffect
에 클린업 함수를 사용하여 이벤트 리스너 제때 제거.
position: fixed;
transform: translateY(50%);
position: fixed;
가 scroll
에 관한 모든 기능을 대체해준다..
function Modal({modalStatus}: Props) {
const card = cards.find((item) => item.id === modalStatus.id)
return <Wrapper>
<ModalBody onMouseDown={(e) => {
e.nativeEvent.stopImmediatePropagation()}
}>
{card ?
<Title>{card.name}</Title>
: null}
</ModalBody>
</Wrapper>
}
코드가 확 줄었다..
position: fixed;
를 추가한 CSS
부분
const ModalBody = styled.div`
position: fixed;
margin: 0 auto;
transform: translateY(50%);
left: 0;
right: 0;
width: 500px;
aspect-ratio: 1;
text-align: center;
background-color: ${props => props.theme.dark.bg.primary};
color: white;
border: 1px solid ${props => props.theme.dark.border.primary};
border-radius: 10px;
`
window.scrollY
position: fixed
window.scrollY
position: fixed;
위 두 방식중 position: fixed
를 사용하는 것이 훨씬 자연스럽다.
scrollY
로 했을 때는 scroll 업다운을 할때 지속적으로 연산된 것이 반영되어 Modal
컴포넌트가 리렌더링되므로 조금씩 잔상이 생기는 것으로 보인다.