• [React] react-router v6 에서 Prompt 구현하기 :: 마이구미
    React 2022. 4. 17. 11:54
    반응형
    이 글은 네비게이션 가드라고 불리는 기능을 위한 Prompt 를 다룬다.
    페이지 뒤로가기 또는 다른 페이지 이동으로 하면, 바로 페이지 전환이 일어난다.
    때로는 Confirm 과 같은 창을 통해 페이지 이동을 막고 제어하는 것을 원할 수 있다.
    이 기능을 네비게이션 가드라고 부를 수 있다.
    react-router v6 를 기준으로 한다.
    이전에는 v4 를 기준으로 작성한 적이 있다. (https://mygumi.tistory.com/358)
    예제 코드 - https://codesandbox.io/s/ljn1r8

     

    현재 기준으로react-router 의 버전은 6.x 까지 올라왔다.

    major 버전이 올라간 만큼 v5 에서 v6 로 마이그레이션 하는 과정은 수정이 좀 필요하다.

    그 과정 중 네비게이션 가드를 위해 Prompt, history.block 등과 같은 기능을 사용했다면, 조금 곤란한 상황이 온다.

    왜냐하면, v6 에서는 관련 기능이 제외되고 릴리즈되었다.

     

    불안정하여 우선순위를 뒤로 미뤘다고한다.
    언제 다시 추가되겠지만, 시기는 알 수 없다.

    관련 이슈는 계속 대화가 진행 중이다.

     

    v6 에서 네비게이션 가드 기능을 사용하기 위한 방법은 다음과 같다.

     

     

    v6 알파버전에서는 이 기능이 구현되었지만, 추후에 제외된 모습을 볼 수 있다.

    그래서 버전(6.0.0-alpha.5)을 낮추고 사용하는 방법이 존재한다.

    하지만 이 방법은 6.x 버전에서 이 기능을 제공해줄때까지 릴리즈 버전이 아닌 불안정한 알파 버전을 사용할 수 밖에 없다는 이슈가 존재한다.

     

    자체 구현은 직접 이 기능을 구현하는 것을 말한다.

    안정성을 보장할 순 없지만, 기존에 넣었다가 제거한 코드에서 도움을 얻을 수 있다.

    커밋 히스토리를 통해 제거된 기능들을 다시 활용하는 것이다.

    히스토리를 통해 usePrompt. useBlock, Prompt 가 제거된 모습을 볼 수 있다.

     

    주요 코드(usePrompt.ts)를 참고하면서 보길 바란다.

    v6 에서는 History 가 아닌 Navigator 가 주 객체로 사용된다.

    타입 기준으로 보면 다음과 같다.

     

    export declare type Navigator = Pick<History, "go" | "push" | "replace" | "createHref">;

     

    History 를 기반으로 사용하는 타입만 Pick 하는 모습을 볼 수 있다.

    네비게이션 가드를 위해 History 내에 존재하는 "block" 을 추가로 정의해야한다.

    history.block 은 실질적으로 history stack 의 변화를 방지하는 메소드이다.

     

    interface Navigator extends BaseNavigator {
      block: History['block']
    }

     

    간략히 정리하면, 적용했다가 제거된 usePrompt, useBlocker 를 다시 적용한 것이다.

    자세한 내용은 예제 코드를 참고하면 된다.

    예제 코드는 기본 window.confirm 창이 아닌 커스텀 모달창을 기준으로 작성되었다.

     

     

     

     

    정확히 어떤 점이 문제가 되서, 이 기능을 제외한 건지는 모르겠다.

    큰 문제점은 발견하지 못했고, 아쉬운 부분은 다음과 같다.

    새로고침 or 직접 URL 을 변경하여 접근하는 경우, React 쪽에서는 이를 탐지하는 것에 어려움이 있다.

    그래서 이 경우에는 커스텀 컨펌창이 아닌 window.confirm 창이 노출된다.

     


     

    v6.3.0 보다 높은 버전을 사용한다면, 위 예제를 사용할 수 없다.

    6.4 버전부터 임시로 사용하던 기능까지 영향을 끼쳐 navigaor.block is not a function 관련 오류를 겪게 된다.

    현재 블로킹 기능 지원을 고려하고 있어서 6.3.0 으로 고정해서 사용하고 있다가 버전을 업데이트하거나 다른 대안이 있긴하다.

    하지만 현재로썬 마땅치 않아서 조금 기다려야봐야할 것 같다.

     

    "react-router-dom": "6.3.0",

     

    https://github.com/remix-run/react-router/pull/9709https://stackoverflow.com/questions/74106591/getting-navigator-block-is-not-a-function-while-navigating-to-other-page

    반응형

    댓글

Designed by Tistory.