로그인 페이지로 Redirect하기 전 안내 toast 띄우기

Sheryl Yun·2022년 10월 3일
0

프로젝트: Effitizer 

목록 보기
12/12
post-thumbnail

Effitizer 프로젝트의 메인 페이지에는 '지금 구독하기' 버튼이 있다.
원래는 로그인이 되어 있지 않을 때 이 버튼을 누르면 구독 페이지가 아닌 로그인 페이지로 바로 이동했었다.

하지만 아무런 안내 없이 이렇게 리다이렉트 되면 사용자가 불편하다고 느낄 수 있겠다는 생각에 '로그인 페이지로 이동할 것'을 예고하는 toast UI를 추가하기로 했다.

과정

프로젝트가 Next.js + Typescript로 진행되어서 '지금 구독하기' 버튼은 Link 컴포넌트를 사용하고 있었다.

<Link href="/subscribe" passHref>
	<a className={styles.subscribeButton}>
		지금 구독하기
        <ArrowIcon width={48} height={48} color="currentColor" />
    </a>
</Link>

Link 컴포넌트는 a 태그와 유사하기 때문에 클릭 시 href의 경로로 이동하는데, toast를 띄워주려면 이 이동을 잠시 막을 필요가 있었다.

그래서 스타일 넣는 용도였던 하위 a 태그에 onClick으로 클릭 이벤트를 막는 코드를 추가하였다.

<Link href="/subscribe" passHref>
	<a 
    	onClick={(e) => { 
        	e.preventDefault(); 
        }}
    	className={styles.subscribeButton}
    >
		지금 구독하기
        <ArrowIcon width={48} height={48} color="currentColor" />
    </a>
</Link>

그리고 여기서부터 난관이 시작되었다. (...)

session 객체가 null인지 여부로 로그인 여부를 분기하고, showToast라는 함수를 만들어 안에 react-toastify의 코드를 넣고, 렌더링을 위한 <ToastContainer /> 컴포넌트도 추가하였으나 코드가 예상대로 동작하지 않았다.

showToast의 console은 찍혔지만 화면에 뜨는 toast의 UI의 모습이 이상했고, delay 시간을 줬다고 생각했는데 기다림 없이 바로 로그인 페이지로 넘어갔다.

  import { useSession } from 'next-auth/react';
  import { ToastContainer, toast } from 'react-toastify';
  
  ...
  
  const { data: session } = useSession();
  
  ...
  
  const showToast = (e: React.MouseEvent) => {
    e.preventDefault(); // 링크 이동 막음
    
    console.log('toast 보여주기!');

    toast.info(
      '구독하시려면 로그인이 필요합니다 😊',
      {
        autoClose: 2000,
        position: toast.POSITION.TOP_RIGHT,
      }
    );
  };
  
  ...
  
  <Link href="/subscribe" passHref>
	<a 
    	onClick={
        	session === null 
            	? (e) => showToast(e) 
            	: () => {}
        }
    	className={styles.subscribeButton}
    >
		지금 구독하기
        <ArrowIcon width={48} height={48} 
        color="currentColor" />
        <ToastContainer />
    </a>
</Link>

다시 살펴보니 autoClose 시간을 setTimeout의 delay 시간과 혼동했고, react-toastify에 필요한 css CDN이 빠져 있었음을 알게 되어 추가하였다.

처음에는 showToast 함수를 setTimeout 안에 넣었는데, 생각해보니 subscribe 페이지로 이동하는 코드가 2초 뒤에 나타나야 했기 때문에 router.push 코드로 대체했다.

  <Link href="/subscribe" passHref>
	<a 
      onClick={
         session === null
            ? (e) => {
                showToast(e);
                setTimeout(() => {
                  router.push('/login');
                }, 2000);
              }
            : () => {}
            }
      className={styles.subscribeButton}
    >
		지금 구독하기
        <ArrowIcon width={48} height={48} 
        color="currentColor" />
        <ToastContainer />
    </a>
</Link>

도중에 <ToastContainer />를 넣는 위치와 toast가 뜨는 시점 조절을 위해 async/await, useEffect 등을 사용해보는 등 여러 시행착오가 많았지만 큰 과정은 위와 같은 과정을 거쳤고, 결국 원하는 동작을 구현하는 데 성공했다.

구현에 성공한 동작

  1. 로그인을 안 했을 때 - '지금 구독하기' 버튼 클릭 시 로그인 페이지로 이동할 것을 안내하는 toast UI가 화면 우상단에 띄워지고, 2초 뒤 로그인 페이지('/login')로 이동
  2. 로그인을 했을 때 - '지금 구독하기' 버튼 클릭 시 바로 구독 페이지('/subscribe')로 이동
profile
데이터 분석가 준비 중입니다 (티스토리에 기록: https://cherylog.tistory.com/)

0개의 댓글