React

[React] Prompt 커스텀해서 제어하기 :: 마이구미

mygumi 2019. 10. 3. 12:53
반응형
이 글은 react-router 에서 제공하는 Prompt 컴포넌트를 다룬다.
페이지 뒤로가기 또는 다른 페이지 이동으로 하면, 바로 페이지 전환이 일어난다.
때로는 Confirm 과 같은 창을 통해 페이지 이동을 막고 제어하는 것을 원할 수 있다.
react-router(v4) 를 사용하고 있다면, 쉽게 제공해주는 <Prompt> 으로 해결할 수 있다.
참고 링크 - https://medium.com/@michaelchan_13570/using-react-router-v4-prompt-with-custom-modal-component-ca839f5faf39

 

브라우저에서 뒤로가기 뿐만 아니라 페이지 이동을 막는 것이 필요한 경우가 많다.

이를 해결하기 위한 방법으로 네비게이션 가드(Navigation Guard) 라고 불린다.

 

Vue 개발을 할 때는 제공해주는 네이베이션 가드를 이용했다.

(https://router.vuejs.org/kr/guide/advanced/navigation-guards.html)

 

const router = new VueRouter({ ... })

router.beforeEach((to, from, next) => {
  // ...
})

 

이러한 로직이 컴포넌트 형태로 존재하면 좋겠다는 생각을 했었다.

React 개발을 하면서 네비게이션 가드가 필요해서 찾아본 결과 원하는 형태를 제공해주고 있었다. (react-router v4 기준)

 


 

왜 네비게이션 가드가 필요한가?

당연히 개발자 입장에서는 페이지 이동 사이의 어떤 작업이 필요로 하기 때문에, 우선 blocking 을 시킬 것이다.

개발적인 면이 아니라면, 단순히 사용자에게 알림 및 경고를 주기 위함이다.

예를 들어, 폼을 다 채우지 않거나 중요한 페이지에서 실수로 이동할 경우가 존재할 수 있다.

이러한 경우를 위해 우리는 사용자에게 한번 더 선택지를 제공해줄 수 있다.

 

 

위와 같은 창을 필요로 할 경우는 다양하게 존재한다.

직접 Confirm 창을 구현하고, 뒤로가기 버튼의 경우에는 onpopstate 를 사용하고... 등등 구현할 수 있다.

하지만 깔끔하지 못할 것이고, 번거로운 작업이 될 것이다.

결국은 페이지 이동에 있어, 중간 네비게이션 역할을 해줄 수 있는 게 존재하면 수월하다.

이를 위해 react-router 에서 제공해주는 <Prompt> 를 사용하면 쉽게 해결할 수 있다. (react-router => Prompt)

 

<Prompt when={canNavigate} message="Are you sure you want to leave?" />

 

 

 

코드 한줄을 통해 라우터 이동이 발생하면, Confirm 창이 뜨고, 사용자 선택에 따라 결정될 수 있다.

공식 문서에 따르면, <Prompt> 에서 제공하는 인자는 when 그리고 message 가 존재한다.

when 인자는 단순히 boolean 값이고, 이 값을 통해 네비게이션 여부를 제어하면 된다.

message 인자를 통해 원하는 문자를 노출해주면 된다.

결과적으로 모든 것이 코드 한줄로 해결된다.

 

하지만 노출되는 창은 커스텀하고 싶은 욕구를 느낄 수 있거나 느껴야하는 상황이 존재한다.

사실 이 글의 본론은 <Prompt> 를 커스텀하는 것이다.

문서는 그렇게 친절하지 않아, 어떻게 커스텀해야할 지 느끼기 쉽지 않다.

공식 문서에서, message 인자는 string 형태와 function 형태 2가지가 존재한다.

 

Will be called with the next location and action the user is attempting to navigate to. Return a string to show a prompt to the user or true to allow the transition.

 

1. 사용자가 시도하려는 next location 과 action 이 호출된다.

2. message 는 문자열 또는 true 값을 리턴하면 prompt 창이 보여진다.

 

사실 커스텀을 위해 필요한 정보는 이동할 location 정보, prompt 창 노출여부를 제어할 수 있으면 된다.

그렇기에, 우리는 위 2가지를 통해 커스텀의 길을 파악할 수 있다.

 

1번은 우리는 next location 을 얻을 수 있다는 것을 의미한다.

2번은 반대로 message 에 false 를 리턴하면 어떻게 되는가?

아무 일도 일어나지 않는다. 당연히 prompt 창이 뜨지 않는다.

하지만 prompt 컴포넌트 자체를 off 한 것이 아니기 때문에, 페이지 이동은 막은 상태이다.

그렇다면, 이 시점에 우리는 커스텀 Prompt 창을 띄우면 된다.

그리고 blocking 여부에 따라, 1번을 활용해서 next location 으로 이동해주면 된다.

 

더 자세히 설명하려고 했으나, 코드를 보고 이해하는 것이 더 낫겠다고 판단했다.

참고한 글은 class 형태로 작성되었고, 본인은 hook 을 통해 작성하였다.

전체 코드는 다음 링크를 참고바란다.

https://codesandbox.io/s/custom-prompt-of-react-router-lpcsv

반응형