본문 바로가기

STUDY/React

React | 페이지 이동 제어하기 ( prevent navigation | react-router-dom Prompt Custom)

무언가를 작성하다가 저장하지 않고 해당 페이지를 나가려고 할 때, 제어하는 방법..

 

0. react-router-dom 설치

설치되어 있지 않다면 install해주기

$ npm i react-router-dom

 

1. Prompt?

react-router-dom에서 제공해주는 api로, 유저가 다른 페이지로 이동하려고 할 때 렌더된다.

when은 말그대로 Prompt가 언제 실행되는지 설정하는 것으로 true/false값을 받는다.

message는 String값 혹은 Fuction을 넣을 수 있다.

<Prompt 
	when={true}
    message="페이지를 떠나시겠습니까?"
/>

 

2. 커스텀해보기

현재 제작중인 웹 애플리케이션에서 저런 alert은 전혀 사용하고 있지 않기 때문에... 커스텀하여 모달로 띄우기로 한다.

이렇게..

 

2-1. Prompt를 언제 띄울지 설정해주기

무엇인가를 한 번이라도 수정하고, 페이지를 나가려고 하면 그 때 띄울것이다. when값에 넣어줄 boolean state를 만들었다.

const [shouldConfirm, setShouldConfirm] = useState(false);

 

그리고 when에 전달해준다. shouldConfrim이 true라면 Prompt가 렌더되도록.

<Prompt when={shouldConfirm} message={handlePrompt} />

 

2-2. message에 function전달하기

위에 handlePrompt가 이미 message에 넣어져있다.. 만들자...

message에는 String혹은 function값을 받는다. function에는 location값이 인자값으로 전달되는데, 이 location에 사용자가 이동하려고 했던! path값이 담겨온다.

 

출처: https://reactrouter.com/core/api/Prompt

isLeave값이 false고 shouldConfirm이 true면? return false(페이지 이동을 막는다)

nextLocation이라는 state에 사용자가 이동하려고 했던! path값을 저장

const handlePrompt = (location) => {
    if (!isLeave && shouldConfirm) {
      setNextLocation(location.pathname);
      setShowConfirmModal(true);
      return false;
    }
    return true;
};

 

2-3. 모달에서 받은 값을 이용해..

위에서 사용한 isLeave값은 모달에서 '나가기'버튼을 클릭했을 때 true로 변경됩니다.

const [isLeave, setIsLeave] = useState(false);

 

isLeave값이 변경되면... useEffect가 실행되고, true일 때 아까 담아둔 nextLocation값으로 history.push해줍니다.

  useEffect(() => {
    if (isLeave) {
      setShouldConfirm(false);
      return history.push(nextLocation);
    }
  }, [isLeave, history]);

 

 

자료를 보면서 많이 헤매서 쉽게 기록해놓으려 했는데 잘 안된다..

정리해보자면

  1. Prompt는 when이 true면 실행된다.
  2. message에 함수를 전달할 수 있고, 그 전달된 함수에 location값이 받아진다.
  3. 모달을 띄워 페이지를 정말 이동 할건지에 대한 값을 받는다.
  4. 그 값을 이용해 Prompt를 제어한다.

암튼 좋은 기능같다...

 

 

참고

 

React Router: Declarative Routing for React

Learn once, Route Anywhere

reactrouter.com

 

 

Using React-Router v4 Prompt with custom modal component

A simple solution to implement custom modal on each scene using React-Router v4 Prompt.

medium.com