기존에 유저의 액션의 성공/실패 여부를 빠르게 만들기 위해서 Alert
로 사용하였다. 그래서 이번에 시간이 남았을 때, Alert
기능 대신 Toast
기능을 사용하려고 하였다.
현재 어드민 페이지는, shadcn-ui
의 디자인을 따라갔다. 그리고 애니메이션의 라이브러리는 아직 도입하지 않았던 상태이다.
프로덕션에서는 Toast
를 만들었기 때문에, 그 기능을 그대로 가져오려고 하였다.
Toast
에 대해서 구글링을 검색하였는데, 한 레딧에서 Toast UI
vs sonner
을 투표하였다. 그 결과 sonner이 거의 5.5~6으로 이겼어서, 나는 인터넷에 npm i sonner
를 검색하였다.
생각보다 많은 다운로드 수를 기록해있고, 공식 홈페이지에서 찾아보니, 내가 필요했던 기능들로 구성되어있어서 이것을 사용하기를 결심하였다.
npx shadcn@latest add sonner
shadcn
에서 sonner
을 제공함으로 나는 위의 방식대로 다운로드하였다.
npm i sonner
다음과 같은 방법으로도 다운로드가 가능하다.
import { Toaster } from "@/components/ui/sonner"
export default function RootLayout({ children }) {
return (
<html lang="en">
<head />
<body>
<main>{children}</main>
<Toaster />
</body>
</html>
)
}
sonner
은 크게, Toast의 디자인을 꾸며주는 Toaster
와 실제 Toast의 기능적인 부분을 담당하는 toast
로 구성된다.
그리고 꼭 상단 layout.tsx
파일에 <Toaster />
을 입력해야한다.
만약 위와 같이 진행하지 않고, component
안마다 <Toaster />
을 작성한다면,
- Toast 사용 시 UI가 버벅 거림의 렌더링
<SignInForm />
컴포넌트에서 성공/실패 시<Toaster />
를 부르고, 성공했을 때<Dashboard />
컴포넌트로 넘어가게 된다면,dulation
을 무시하고, 페이지가 넘어가지면,<Toaster />
의 UI가 없어지게 된다.
그래서 반드시 제일 app.tsx
혹은 layout.tsx
페이지 안에 작성해야한다.
sonner
라이브러리의 사용 방법은 다음과 같다.
// 성공
toast.success("Success")
// 실패
toast.error("Error")
// 경고
toast.warning("Warning")
// 정보
toast.info("Info")
...
나는 성공/실패/경고/정보
의 타입 유형만 사용하고, 이것을 useToast()
의 hooks
를 통해서 관리해주는 것이 좋아보였다.
그래서 useToast()
훅을 만들었다.
import { toast } form "sonner";
interface IToast {
message: string;
type?: "success" | "error" | "warning" | "info"
}
export const useToast() => {
const addToast = ({ messgage, type = "success" } : IToast => {
if ( type === "success" ) toast.success(message);
if ( type === "error" ) toast.error(message);
if ( type === "warning" ) toast.warning(message);
if ( type === "info ) toast.info(message);
}
return { addToast }
}
// switch 문
export const useToast = () => {
const addToast = ({ message, type = "success" }: IToast) => {
switch (type) {
case "error":
toast.error(message);
break;
case "warning":
toast.warning(message);
break;
case "info":
toast.info(message);
break;
default:
toast.success(message); // default fallback
break;
}
};
return { addToast };
};
if
문으로 뺐는데, case
문이 더 적합할 것 같다. 내일 case
문으로 수정해서 배포해야겠다.
layout
파일에는 모두 Component
로 구성되어 있는 걸 선호하여서 <Toaster />
의 스타일을 적용하기 위해서 <Toast />
컴포넌트를 만들었다.
import { Toaster } from 'sonner';
export const Toast = () => {
return (
<Toaster />
)
}
이 때 richColors
의 속성을 적용하면, toast
를 구성하는 type (예: 성공/실패/경고/정보)
별로의 색상들이 지정된다.
그리고 맨 위 그리고 가운데에 Toast
의 위치를 설정해주고 싶어서 position="top-center"
를 duration={1500}
로 설정했다.
import { Toaster } from "sonner"
export const Toast = () => {
return (
<Toaster richColors position="top-center" duration={1500} />
)
}
으로 설정하였다.
...
const { addToast } = useToast();
...
onSuccess: () => {
addToast({
message: "Event has been created",
});
},
...
위와 같은 방식으로 편하게 사용하면 된다.
그러면 쉽게 Toast
를 만들 수 있다. 끝.