개발/프로젝트
새로고침/뒤로가기 시도 시 모달 띄우기
xuwon
2025. 5. 27. 15:44
일기 작성 페이지에서 새로고침, 뒤로가기 등을 시도할 때 이동을 막고 경고 모달을 띄우려고 한다.
const router = useRouter();
const pathname = usePathname(); // 현재 경로
const lastPathname = useRef(pathname); // 이전 경로 저장
useEffect(() => {
if (pathname !== lastPathname.current) {
// 페이지 이동 시도 감지
setShowSaveRestrictionModal(true); // 모달 띄우기
router.replace(lastPathname.current); // 현재 페이지로 강제 이동 → 이동 막기
}
}, [pathname, router]);
pathname이 바뀌면, 즉 사용자가 라우터 이동을 시도하면 감지됨
그리고 router.replace(lastPathname.current)를 통해 현재 페이지로 강제 이동을 시킨다.
→ 페이지 변경 X
useEffect(() => {
const handleBeforeUnload = (e: BeforeUnloadEvent) => {
e.preventDefault(); // 크롬 기준으로 꼭 넣어야 동작
e.returnValue = ''; // 브라우저 기본 경고창 띄움
};
window.addEventListener('beforeunload', handleBeforeUnload);
사용자가 브라우저에서 새로고침이나 탭을 닫을 때, 브라우저 기본 경고창을 띄운다.
(beforeunload 이벤트)
이건 커스텀 모달은 못 넣는다고 한다.
window.history.pushState(null, '', window.location.href);
히스토리(브라우저의 방문 내역 스택)에 현재 상태를 강제로 push하는 코드.
브라우저 자체의 뒤로가기 버튼을 눌렀을 때 페이지가 이동하는 것을 방지하기 위해서 덫을 깔아놓는 셈이다.
const handlePopState = () => {
setShowSaveRestrictionModal(true); // 모달 띄우기
window.history.pushState(null, '', window.location.href); // 다시 현재 주소 push
};
window.addEventListener('popstate', handlePopState);
여기서 popstate 이벤트는 뒤로가기(or 앞으로가기) 할 때 발생된다.
이때 내가 만든 모달을 띄우고, 또 현재 주소를 push 해서 히스토리를 원래대로 되돌린다.
→ 뒤로가기 클릭 무력화
return () => {
// 클린업
window.removeEventListener('beforeunload', handleBeforeUnload);
window.removeEventListener('popstate', handlePopState);
};
}, []);
컴포넌트 언마운트 시 이벤트 리스너 정리!
어렵다.
