myeonjeobeottae / client

0 stars 0 forks source link

useRouteControl 구현 #17

Open tangjinlog opened 6 months ago

tangjinlog commented 6 months ago

Feature

Description

Troubleshooting

tangjinlog commented 6 months ago

Next.js - useRouter router.events.on('routeChangeStart')로 Routing 감지 시,

<a/>의 외부 링크로의 Routing은 window.addEventListener('beforeUnload')가 감지해서, 나가기 confirm modal이 뜸.

tangjinlog commented 6 months ago

Error 뒤로가기

 구분  ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ설명 ㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤㅤ
현상 뒤로가기 버튼route.back()이 동작하지 않음
원인 image
router.asPath(현재url)와 nextUrl(routeChangeStart)을 비교해서 다르면 컨펌모달을 띄워주고 있는데,
뒤로가기 버튼 클릭 시, 페이지 이동을 막아도 router.back()으로 인한 history stack이 지워지는 건 막을 수 없는 것 같음.
따라서 history stack의 어떤 꼬임으로 뒤로가기 버튼이 작동하지 않는다고 추측. 관련된 2가지 문제가 발생했다.

1. 한 번이라도 뒤로가기 버튼을 클릭 후 funnel의 다음 step에서 뒤로가기 버튼을 클릭하면, 첫 번째 클릭 시, 아무런 반응이 없고, url만 바로 전 url로 변경된다.
그리고 두 번째 클릭 시, 원래는 funnel의 첫 step에서 뒤로가기 버튼 클릭 시에만 떠야 할 컨펌모달이 다른 step에서 뜬다.

2. 루트로 이동하는 메인로고 버튼을 클릭하고 컨펌모달에서 취소한다음, funnel의 뒤로가기 버튼을 클릭하면 메인로고 버튼을 클릭한 횟수+1 만큼 클릭해야 컨펌모달이 뜬다.
해결책 1. router.back()으로 인한 history stack이 제거 되므로, window.history.pushState(null, '',router.asPath) 로 stack을 추가해주면서 현재 url을 유지시켰다. 그런데 뒤로가기 버튼을 클릭할 때마다, history stack이 계속해서 줄어드는 것은 막았지만, 처음 stack이 변경되는 것은 막을 수 없었다. 따라서 router.replace(router.asPath) 해주면서 해결.

- ex) router.replace() 적용 안했을 때

funnel 첫 진입 시 : /chat/custom
뒤로가기 버튼 클릭 : /chat(history stack) , /chat/custom?funnel-step=position(pushState,현재url)
다음 스텝 이동 : /chat/custom?funnel-step=stack
뒤로가기 버튼 클릭 : /chat/custom?funnel-step=position(페이지 이동 일어나지않음 - pushState로 추가한 stack)
뒤로가기 버튼 클릭 : /chat/custom?funnel-step=stack(pushState)
지금funnel-step이 stack인 상태에서 컨펌 모달이 뜨는 오류 발생

- ex) router.replace() 적용

funnel 첫 진입 시 : /chat/custom
뒤로가기 버튼 클릭 : /chat/custom(history stack, router.replace()) , /chat/custom?funnel-step=position(pushState,현재url)
다음 스텝 이동 : /chat/custom?funnel-step=stack
뒤로가기 버튼 클릭 : /chat/custom?funnel-step=position(페이지 이동 - router.replace()로 초기화된 stack)
뒤로가기 버튼 클릭 : /chat/custom?funnel-step=position
정확히 funnel-step=position에서 컨펌모달이 뜸

2. router.back()으로 history stack이 지워지는게 아닌, 단순 루트로의 이동시에도 history.pushState로 stack을 추가 하고 있었기 때문에 발생.
따라서 조건부로 nextUrl !== '/' 일때만 stack을 추가하도록 변경하면서 해결.
const syncUrlWithRouter = useCallback(
        (nextUrl: string) => {
            console.log(router.asPath, window.location.pathname);
            if (router.asPath !== window.location.pathname) {
                //FIXME: 루트 이동 말고도 다른 path가 추가 될 여지 있음
                if (nextUrl !== '/') {
                    //현재 path 유지
                    window.history.pushState(null, '', router.asPath);
                    //뒤로가기 버튼 클릭 전 path로 초기화
                    router.replace(router.asPath);
                }
            }
        },
        [router.asPath, nextUrl],
    ); 

2c6d6c2