현재: next 14 version의 next/navigation을 사용
처리해야할 경로: main/page.tsx와 동적 라우팅 경로인 room/[id]/page.tsx
방입장: rotuer.push / 방나기: router.replace
수행할 로직: main -> room/[id] 이동 후 뒤로가기 클릭 시
PopState Evenet
실행시켜 조건부 렌더링인<Loading/>
컴포넌트를 통해 방나가기 로직을 수행
문제: main/page.tsx에서
router.push
를 통해 room/[id]/page.tsx 경로로 이동 후 뒤로가기 클릭 시popState
가 정상 작동되지 않는 문제가 발생
이유:
Next.js에서 router.push()를 호출하면 내부적으로 history.pushState()가 실행되지만, Next.js가 SPA(Single Page Application) 구조로써, 브라우저의 페이지를 리로드하지 않고 클라이언트 측에서 URL을 변경하고 컴포넌트를 렌더링하기 때문에 브라우저의 Popstate 이벤트가 이러한 변화를 감지하지 못해 작동되지 않는 문제가 발생한다.
history API를 활용하여 hisyory를 조작
pushState
를 활용하여 현재 roomPage의 history를 추가하였다.popState
가 정상작동되는 걸 볼 수 있다. useEffect(() => {
// history 목록에 추가
history.pushState(null, "", "")
const handlePopstate = () => {
router.replace("/main")
socket.emit("exitRoom", roomId, userId);
};
// 이벤트 리스너 등록
window.addEventListener("popstate", handlePopstate);
return () => {
// 이벤트 리스너 제거
window.removeEventListener("popstate", handlePopstate);
};
}, []);
뒤로가기
시 현재 내 위치는 history 2번째 Main에 위치앞으로가기
시 3번째 history인 Room으로 이동되는 구조로써 Room에 다시 접속하는 문제를 해결해야한다.
- 아래의 로직 해석
- pushState의 첫번 째 매개변수인 state 상태값을 활용:
history.pushState(data, "", "");
- 뒤로가기 및 앞으로가기 등으로 Room Page를 재접속하였으면,
history.state.isAccess
값이 존재하여 main Page로 relpace한다.
useEffect(() => {
const data = { isAccess: true };
// 재 입장 시 history 상태 값이 존재하므로 현재 history를 Main으로 replace한다.
if (history.state.isAccess) {
toast.error("잘못된 접근입니다.");
router.replace("/main");
return;
}
//첫 입장 시 작동하여 현재 history 상태 값에 "isAccess: true" 저장
if (!history.state.isAccess) {
history.pushState(data, "", "");
}
const handlePopstate = (e: PopStateEvent) => {
router.replace("/main")
socket.emit("exitRoom", roomId, userId);
};
// 이벤트 리스너 등록
window.addEventListener("popstate", handlePopstate);
return () => {
// 이벤트 리스너 제거
window.removeEventListener("popstate", handlePopstate);
};
}, []);
한계점: UI에서 깜빡임이 존재 및 그로 인해 UX적으로 실망감을 준다 ㅠㅠ..
📚📚 참고 문서)