
프론트엔드에서 알림을 표시하기 위해 위의 이미지처럼 토스트를 사용하고 있다.
const toast = useToaster();
toast('warn','존재하지 않는 이메일입니다.);
useToaster로 toast를 선언한 다음 toast(알림 종류,메시지)를 하면 토스트가 표시된다.
그런데 한가지 문제가 생겼다. OAuth로 로그인할 때 문제가 생기면 로그인 페이지로 리다이렉트 시키도록 설정했다. 이때 문제가 생겼다는 토스트를 표시해야 하는데 백엔드에서 리다이렉트를 시키기 때문에 토스트를 사용할 수 없었다.
이를 해결하기 위해 쿼리 파라미터를 입력해서 리다이렉트 시키고 이 쿼리 파라미터를 감지해서 토스트를 표시하는 프로바이더를 구현했다.
1.리다이렉트할 때 warn 쿼리 파라미터를 포함해서 리다이렉트 시킨다.
2.프로바이더에서 warn 쿼리 파라미터를 조회한다.
3.경고 메시지를 저장한 상수 객체를 통해 메시지를 불러온다.
4.toast('warn',메시지)로 토스트를 표시한다.
5.warn 쿼리 파라미터를 제거한다.
// @/constants/warningMessages.ts
export const WARNING_MESSAGES = {
emailNotExist : '존재하지 않는 이메일입니다.',
}
// @/providers/warningProvider.tsx
'use client';
import { usePathname, useRouter, useSearchParams } from 'next/navigation';
import { useToaster } from '@/hooks/useToaster';
import { useEffect } from 'react';
import { WARNING_MESSAGES } from '@/constants/warningMessages';
export default function WarningProvider({
children,
}: {
children: React.ReactNode;
}) {
const searchParams = useSearchParams();
const warn = searchParams.get('warn') as keyof typeof WARNING_MESSAGES;
const toast = useToaster();
const router = useRouter();
const pathname = usePathname();
useEffect(() => {
if (warn && warn.length && warn in WARNING_MESSAGES) {
toast('warn', WARNING_MESSAGES[warn]);
}
if (warn) {
const newParams = new URLSearchParams(searchParams.toString());
newParams.delete('warn');
const queryString = newParams.toString();
const newPathname = queryString ? `${pathname}?${queryString}` : pathname;
router.replace(newPathname);
}
}, [searchParams, warn]);
return <>{children}</>;
}
이렇게 구현하고 가장 상단 layout에 해당 프로바이더를 감싸주면 어느 페이지든 뒤에 ?warn='메시지 키'를 입력해주면 메시지 키에 해당하는 메시지가 토스트로 표시된 다음 warn 쿼리 파라미터가 제거된다.
if (warn) 조건문 안에 있는 코드를 통해 warn 외에 입력된 쿼리 파라미터가 있다면 해당 쿼리 파라미터는 유지하고 warn만 제거할 수 있다.
이렇게 구현함으로써 OAuth뿐만 아니라 Next.js 미들웨어에서 리다이렉트 시킬 때도 경고 토스트를 표시할 수 있었다.
이런 토스트 뿐만 아니라 프론트엔드에서 작업이 필요한데 백엔드나 Next.js 미들웨어에서 리다이렉트를 시키기 때문에 프론트에서 직접 통제가 불가능한 경우에 모두 적용할 수 있는 기능이다.