오늘은 모달이 떠있는 상태에서 스크롤이 안되도록 처리해보겠습니다. 방법은 아주 간단합니다! 모달을 띄울 때, body의 style로 overflow hidden을 주면 됩니다. 반대로, 모달을 닫을 땐 overflow 속성을 지워주면 되겠죠?
import { useCallback } from 'react';
export function useBodyScrollLock() {
const lockScroll = useCallback(() => {
document.body.style.overflow = 'hidden';
}, []);
const openScroll = useCallback(() => {
document.body.style.removeProperty('overflow');
}, []);
return { lockScroll, openScroll };
}
모달 컴포넌트가 작성되어 있는 상황을 가정해봅시다. 그러면 코드는 아래와 같아지겠죠.
const Component: FC<Props> = ({ label, imageSource }) => {
const [isOpen, setIsOpen] = useState(false);
const { lockScroll, openScroll } = useBodyScrollLock();
const handleOpen = () => {
lockScroll();
setIsOpen(true);
};
const handleClose = () => {
openScroll();
setIsOpen(false);
};
return (
<div>
<div onClick={handleOpen}>
<img
src={imageSource}
alt={label}
></img>
</div>
<span>{label}</span>
{isOpen && (
<Modal
isOpen={isOpen}
handleClose={handleClose}
/>
)}
</div>
);
};
단순하게 위 코드로만 테스트했을 때, IOS Chorome/Safari에선 overflow hidden이 정상적으로 작동되지 않는 문제가 있었습니다. 따라서 스크롤이 되지 않도록 처리하는 코드를 추가해줘야 하는데요. 아래와 같이, position fixed를 주고, top 위치로 사용자가 스크롤한 위치만큼 -로 계산해주는 것입니다. 그러면 overflow 속성 없이도 스크롤을 막아줄 수 있습니다.
import { useCallback } from 'react';
export function useBodyScrollLock() {
let scrollPosition = 0;
const lockScroll = useCallback(() => {
// for IOS safari
scrollPosition = window.pageYOffset;
document.body.style.overflow = 'hidden';
document.body.style.position = 'fixed';
document.body.style.top = `-${scrollPosition}px`;
document.body.style.width = '100%';
}, []);
const openScroll = useCallback(() => {
// for IOS safari
document.body.style.removeProperty('overflow');
document.body.style.removeProperty('position');
document.body.style.removeProperty('top');
document.body.style.removeProperty('width');
window.scrollTo(0, scrollPosition);
}, []);
return { lockScroll, openScroll };
}
이상으로 설명을 마치겠습니다. 읽어주셔서 감사합니다!
반응형
'Framework > React & RN' 카테고리의 다른 글
[React] Creact React App을 분석해보자 (1) | 2022.04.26 |
---|---|
[React] CRA 없이, 리액트 개발 환경을 설정해보자 (0) | 2022.04.21 |
[React] 리스트에 key 값을 잘못 입력하면 어떻게 될까? (0) | 2022.04.14 |
[Expo 44] 최신 Expo 환경에서 복수 이미지 업로드하는 방법 (0) | 2022.04.02 |
React Native/Typescript 환경에서 react-navigation을 활용하여 라우팅하는방법 (0) | 2022.04.02 |
댓글