• Feed
  • Explore
  • Ranking
/
/
    Next.js

    Next.js에서 Route 및 페이지 이탈 방지하기

    Next.js에서 useRouter를 활용해 사용자가 특정 조건에서 페이지를 떠나는 것을 방지하는 방법을 설명합니다.
    Next.jshooks
    m
    morethanmin
    2024.12.29
    ·
    5 min read

    해당 아티클은 next.js의 pages router를 기준으로 작성되었습니다.

    이탈 방지 훅의 필요성

    사용자가 중요한 데이터를 입력하거나 작업을 진행 중일 때, 페이지를 실수로 떠나거나 이동하면 불편함을 초래할 수 있습니다. 이를 방지하기 위해 페이지 이탈 시 사용자에게 경고를 표시하거나 특정 작업을 수행할 수 있는 기능을 구현하는 경우들이 존재합니다.

    이 글에서는 Next.js에서 useRouter와 브라우저의 beforeunload 이벤트를 활용해 route 및 페이지 이탈을 방지하는 useBlockRouteChange 훅을 만들어보겠습니다.


    훅 설계 및 구현

    아래는 이탈 방지 훅 useBlockRouteChange의 구현 코드입니다. 이 훅은 사용자가 페이지를 떠나려고 할 때 특정 동작을 실행하거나 이탈을 막을 수 있도록 설계되었습니다.

    import { useRouter } from 'next/router';
    import { useCallback, useEffect } from 'react';
    
    const handleBeforeUnload = (e: BeforeUnloadEvent) => {
      e.preventDefault();
    };
    
    const useBlockRouteChange = (onBlock: (blockedUrl: string) => void) => {
      const router = useRouter();
    
      const handleRouteChangeStart = useCallback(
        (url: string) => {
          if (decodeURIComponent(url).includes(decodeURIComponent(router.asPath))) {
            return;
          }
    
          if (router.asPath !== window.location.pathname) {
            window.history.pushState(null, '', router.asPath);
          }
          onBlock(url);
          router.events.emit('routeChangeError');
          throw new Error('routeChangeError');
        },
        [router, onBlock],
      );
    
      useEffect(() => {
        router.events.on('routeChangeStart', handleRouteChangeStart);
        window.addEventListener('beforeunload', handleBeforeUnload);
    
        return () => {
          router.events.off('routeChangeStart', handleRouteChangeStart);
          window.removeEventListener('beforeunload', handleBeforeUnload);
        };
      }, [router.events, handleRouteChangeStart]);
    
      const unblockRoute = () => {
        router.events.off('routeChangeStart', handleRouteChangeStart);
        window.removeEventListener('beforeunload', handleBeforeUnload);
      };
    
      return unblockRoute;
    };
    
    export default useBlockRouteChange;
    

    주요 기능 및 동작 방식

    1. Route 변경 감지

      • Next.js의 router.events를 활용하여 routeChangeStart 이벤트를 구독합니다.

      • 새로운 URL이 현재 URL과 다른 경우, onBlock 콜백을 실행하여 사용자가 수행 중인 작업을 멈출 수 있는 기회를 제공합니다.

    2. 페이지 이탈 방지

      • 브라우저의 beforeunload 이벤트를 등록하여 사용자가 페이지를 떠날 때 브라우저 기본 경고를 표시하거나 동작을 막을 수 있습니다.

    3. 해제 기능 제공

      • 훅이 반환하는 unblockRoute를 호출하면 페이지 이탈 방지 동작을 해제할 수 있습니다. 이로써 상황에 따라 동작을 유연하게 제어할 수 있습니다.


    활용 방법

    아래는 useBlockRouteChange 훅을 실제로 사용하는 예제입니다.

    import { useState } from 'react';
    import useBlockRouteChange from './useBlockRouteChange';
    
    const MyComponent = () => {
      const [isBlocking, setIsBlocking] = useState(true);
    
      const unblockRoute = useBlockRouteChange((blockedUrl) => {
        if (isBlocking) {
          alert(`페이지를 떠나시겠습니까?`);
        }
      });
    
      return (
        <div>
          <p>여기에서 페이지 이탈 방지 로직을 테스트할 수 있습니다.</p>
          <button onClick={() => setIsBlocking(false)}>이탈 방지 해제</button>
          <button onClick={unblockRoute}>훅 동작 해제</button>
        </div>
      );
    };
    
    export default MyComponent;
    

    결론

    useBlockRouteChange 훅은 사용자 작업 중 발생할 수 있는 실수나 의도치 않은 이탈을 방지하는 데 유용합니다. 이를 통해 중요한 데이터를 보호하고 사용자 경험을 개선할 수 있습니다.

    더 나은 개선 아이디어가 있거나 추가 기능이 필요하다면 언제든 의견을 나눠주세요!







    - 컬렉션 아티클