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값이 담겨온다.
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]);
자료를 보면서 많이 헤매서 쉽게 기록해놓으려 했는데 잘 안된다..
정리해보자면
- Prompt는 when이 true면 실행된다.
- message에 함수를 전달할 수 있고, 그 전달된 함수에 location값이 받아진다.
- 모달을 띄워 페이지를 정말 이동 할건지에 대한 값을 받는다.
- 그 값을 이용해 Prompt를 제어한다.
암튼 좋은 기능같다...
참고