React Toast 시스템 설계 가이드 – Notification 알림을 전역에서 관리하는 법
🔔 React 앱에서 Notification / Toast 시스템 제대로 설계하기
모던 웹 앱에서 Toast 메시지(알림/Notification)는 사용자 경험(UX)의 핵심 요소입니다.
요청 성공, 오류 안내, 상태 변화 등을 빠르게 알려주는 이 작은 UI 요소 하나로, 사용자 만족도를 높이고 앱의 완성도를 끌어올릴 수 있습니다.
하지만 단순한 메시지 출력이 아닌, 구조적이고 유연한 알림 시스템을 구현하려면 다음과 같은 사항을 고려해야 합니다:
- 전역 상태에서 관리 가능한 구조
- 다양한 종류/상태/디자인 지원
- 애니메이션 효과와 타이밍 설정
- 중복 제어, 자동 사라짐 기능
📌 1. 왜 직접 Notification 시스템을 설계해야 할까?
물론 외부 라이브러리인 react-toastify
, notistack
등을 사용할 수도 있지만, 다음과 같은 경우에는 자체 구현이 더 유리합니다:
- 디자인 시스템과 완벽하게 맞춰야 할 때
- 글로벌한 토스트 메시지를 모든 페이지에서 사용하고 싶을 때
- 알림 메시지에 커스터마이징 가능한 컴포넌트가 들어갈 때
따라서 기본적인 요구사항부터 단계별로 직접 구현해보는 것이 실력을 쌓는 데에도 좋습니다.
🧱 2. 토스트 시스템의 핵심 구조
React 기반에서 토스트 시스템은 크게 다음과 같이 구성됩니다:
- ToastContext: 알림 추가/삭제 등 전역 API 제공
- ToastProvider: Context와 알림 렌더링 로직을 감싸는 상위 컴포넌트
- useToast Hook: 어디서든 알림을 호출할 수 있도록 하는 커스텀 훅
- Toast 컴포넌트: 실제 UI를 렌더링하고 애니메이션 처리
예시 구조
/components
└── Toast
├── ToastProvider.tsx
├── ToastContainer.tsx
├── ToastItem.tsx
└── useToast.ts
⚙️ 3. 전역 ToastContext 만들기
전역에서 알림을 호출할 수 있도록 Context를 구성합니다.
{`// ToastContext.tsx
import { createContext, useContext } from 'react';
const ToastContext = createContext(null);
export const useToast = () => {
const context = useContext(ToastContext);
if (!context) throw new Error('ToastProvider 내부에서 사용해야 합니다');
return context;
};`}
Provider 내부 상태 예시:
{`const [toasts, setToasts] = useState([]);
const addToast = (toast) => {
const id = uuid(); // 고유한 ID 생성
setToasts(prev => [...prev, { ...toast, id }]);
setTimeout(() => removeToast(id), toast.duration || 3000);
};
const removeToast = (id) => {
setToasts(prev => prev.filter(t => t.id !== id));
};`}
🖼️ 4. 토스트 UI 렌더링과 애니메이션
알림은 화면 특정 영역(보통 우상단)에 쌓이며, 자연스러운 입장/퇴장 애니메이션이 UX에 중요합니다.
ToastContainer.tsx
{`return (
)`}
ToastItem.tsx
{`const ToastItem = ({ message, type, onClose }) => {
return (
);
};`}
간단한 CSS 예시:
{`.toast-wrapper {
position: fixed;
top: 20px;
right: 20px;
display: flex;
flex-direction: column;
gap: 12px;
z-index: 9999;
}
.toast {
padding: 12px 16px;
border-radius: 8px;
background: #333;
color: white;
animation: fadeIn 0.3s ease-out;
}`}
애니메이션에는 Framer Motion
등을 활용하면 더욱 부드럽게 만들 수 있습니다.
🎨 5. 알림 타입과 아이콘, 상태 관리
알림은 일반적으로 다음과 같은 타입으로 구분됩니다:
- ✅ success: 요청 성공
- ⚠️ warning: 주의
- ❌ error: 오류 발생
- ℹ️ info: 일반 안내
ToastItem 컴포넌트에서 해당 타입에 따라 색상, 아이콘 등을 분기합니다.
{`const iconMap = {
success: '✅',
error: '❌',
warning: '⚠️',
info: 'ℹ️',
};
{iconMap[type]} {message}`}
🧠 6. useToast 훅으로 어디서든 호출
이제 실제 사용자는 아래처럼 간단하게 호출할 수 있습니다:
{`const { addToast } = useToast();
addToast({
message: '저장이 완료되었습니다!',
type: 'success',
duration: 3000
});`}
이로써 컴포넌트 내 복잡한 상태관리가 아니라,
전역 Hook을 통해 한 줄로 UX 알림 처리
가 가능합니다.
📈 7. 고급 기능 확장 아이디어
토스트 시스템을 더 유연하게 만들기 위해 다음 기능을 고려해볼 수 있습니다:
- 동일 메시지 중복 방지 (id 또는 내용 기준 중복 체크)
- 최대 표시 개수 제한 (5개 이상이면 오래된 알림 자동 삭제)
- 위치 지정 옵션 (top-left, bottom-right 등)
- persistent 옵션 추가 (닫기 버튼 필수)
- 알림 클릭 시 콜백 실행 (예: 페이지 이동)
이러한 기능은 프로젝트 특성에 따라 선택적으로 구현하면 됩니다.
✅ 마무리 요약
요소 | 전략 |
---|---|
전역 상태 관리 | ToastContext + Provider + useToast 구성 |
UI 렌더링 | ToastContainer에서 map으로 알림 목록 출력 |
자동 제거 | setTimeout으로 일정 시간 후 제거 |
애니메이션 | Framer Motion 또는 CSS Keyframes 활용 |
사용성 | 아이콘, 타입, 위치 지정, 중복 방지 |
React 앱에서 Toast 시스템은 단순한 알림을 넘어서 사용자 흐름을 안내하는 내비게이터 역할을 합니다.
직접 설계하면서 UX 흐름과 구조적 사고를 함께 익히면, 한 단계 더 실력 있는 개발자로 성장할 수 있습니다. 🚀