일상이 개발

React Toast 시스템 설계 가이드 – Notification 알림을 전역에서 관리하는 법

디어노미 2025. 4. 15. 05:56
반응형

🔔 React 앱에서 Notification / Toast 시스템 제대로 설계하기

모던 웹 앱에서 Toast 메시지(알림/Notification)는 사용자 경험(UX)의 핵심 요소입니다.
요청 성공, 오류 안내, 상태 변화 등을 빠르게 알려주는 이 작은 UI 요소 하나로, 사용자 만족도를 높이고 앱의 완성도를 끌어올릴 수 있습니다.

하지만 단순한 메시지 출력이 아닌, 구조적이고 유연한 알림 시스템을 구현하려면 다음과 같은 사항을 고려해야 합니다:

  • 전역 상태에서 관리 가능한 구조
  • 다양한 종류/상태/디자인 지원
  • 애니메이션 효과와 타이밍 설정
  • 중복 제어, 자동 사라짐 기능

📌 1. 왜 직접 Notification 시스템을 설계해야 할까?

물론 외부 라이브러리인 react-toastify, notistack 등을 사용할 수도 있지만, 다음과 같은 경우에는 자체 구현이 더 유리합니다:

  • 디자인 시스템과 완벽하게 맞춰야 할 때
  • 글로벌한 토스트 메시지를 모든 페이지에서 사용하고 싶을 때
  • 알림 메시지에 커스터마이징 가능한 컴포넌트가 들어갈 때

따라서 기본적인 요구사항부터 단계별로 직접 구현해보는 것이 실력을 쌓는 데에도 좋습니다.


🧱 2. 토스트 시스템의 핵심 구조

React 기반에서 토스트 시스템은 크게 다음과 같이 구성됩니다:

  1. ToastContext: 알림 추가/삭제 등 전역 API 제공
  2. ToastProvider: Context와 알림 렌더링 로직을 감싸는 상위 컴포넌트
  3. useToast Hook: 어디서든 알림을 호출할 수 있도록 하는 커스텀 훅
  4. 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 (
{toasts.map(toast => ( removeToast(toast.id)} /> ))}

)`}

ToastItem.tsx

{`const ToastItem = ({ message, type, onClose }) => {
  return (
{message}

  );
};`}

간단한 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 흐름과 구조적 사고를 함께 익히면, 한 단계 더 실력 있는 개발자로 성장할 수 있습니다. 🚀

반응형