프로젝트를 진행하면서 공통 컴포넌트를 먼저 개발하게 되었다.그중에 React-toastify를 사용하여 사용자에게 메세지를 출력해주는 것을 구현 및 학습해보자 또한 어떠한 방식으로 처리해야 효율적으로 관리할 수 있는지 알아보자
npm install react-toastify
<ToastContainer
position="bottom-right"
autoClose={3000}
hideProgressBar={false}
newestOnTop={false}
closeOnClick
rtl={false}
pauseOnFocusLoss
draggable
pauseOnHover
limit={3}
transition={Slide}
pauseOnHover
toastStyle={{ backgroundColor: "#333", color: "#fff" }}
bodyClassName="text-sm font-medium"
theme="light"
/>
| 속성명 | 타입 | 설명 |
|---|---|---|
position | ToastPosition | 토스트가 화면의 어디에 나타날지 설정하는 것 ("top-right", "top-center", "bottom-right" 등) |
autoClose | number | false | 자동으로 닫히는 시간 (ms). false면 수동으로 닫아야 함. |
hideProgressBar | boolean | 진행 바 표시 여부. |
newestOnTop | boolean | 최신 알림을 위에 배치할지 여부. |
closeOnClick | boolean | 클릭 시 닫을 수 있는지 여부. |
rtl | boolean | 오른쪽에서 왼쪽 방향 표시 여부. (아랍어 등) |
pauseOnFocusLoss | boolean | 창이 다른 곳으로 포커스 이동 시 일시정지. |
draggable | boolean | 드래그해서 닫기 가능 여부. |
pauseOnHover | boolean | 마우스를 올리면 일시정지할지 여부. |
theme | "light" | "dark" | "colored" | 테마 색상 |
limit | number | 화면에 표시될 수 있는 최대 토스트 개수 제한 |
containerId | string | 여러 ToastContainer를 쓸 때 특정 ID로 구분 |
enableMultiContainer | boolean | 여러 컨테이너를 동시에 쓸 수 있게 허용 |
transition | Slide, Zoom, Flip, Bounce 등 | 토스트 나타나는 애니메이션 |
icon | boolean | ReactNode | 아이콘을 커스터마이징하거나 제거 가능 |
toastStyle | CSSProperties | 개별 토스트 박스의 인라인 스타일 |
bodyClassName | string | function | 토스트 내부 body에 추가 클래스 적용 |
className | string | function | 컨테이너 자체에 클래스 적용 |
토스트 메시지를 만들때 그냥 사용도 가능하지만 효율성과 확장성을 좋게 하기 위하여 ContextAPI를 활용하여 중앙 집중화를 시켜 관리하면 좀 더 관리하기 쉽다.
import React, { createContext, ReactNode } from "react";
import { toast, ToastContainer } from "react-toastify";
interface ToastContextType {
success: (msg: string) => void;
error: (msg: string) => void;
info: (msg: string) => void;
}
// context 객체 생성
export const ToastContext = createContext<ToastContextType | null>(null);
// ToastProvider 컴포넌트 정의 – 전체 앱 또는 하위 컴포넌트에 토스트 기능 제공
export const ToastProvider = ({ children }: { children: ReactNode }) => {
const success = (msg: string) => toast.success(msg);
const error = (msg: string) => toast.error(msg);
const info = (msg: string) => toast.info(msg);
// Context.Provider로 자식 컴포넌트에 toast 함수를 제공
return (
<ToastContext.Provider value={{ success, error, info }}>
{children}
<ToastContainer
position="bottom-center" //화면의 중앙 아래에 토스트 표시
autoClose={3000} // 3초뒤 자동으로 닫힘
hideProgressBar={false} // 진행바 false
closeOnClick // 클릭시 닫힘
pauseOnHover // 마우스 올리면 시간정지
draggable // 드래그로 닫히기
theme="light" // 밝은 테마
/>
</ToastContext.Provider>
);
};
import { useContext } from "react";
import { ToastContext } from "../context/ToastContext";
export const useToast = () => {
const context = useContext(ToastContext);
if (!context) {
throw new Error("useToast는 ToastProvider 안에서만 사용해야 합니다.");
}
return context;
};
import React from "react";
import { useToast } from "../hooks/useToast";
const LoginButton = () => {
const { success, error } = useToast();
const handleLogin = () => {
// 로그인 성공 예시
success("로그인 성공!");
// 로그인 실패 예시
// error("로그인 실패. 다시 시도해주세요.");
};
return <button onClick={handleLogin}>로그인</button>;
};