[Context API]React-toastify 학습하기

김민석·2025년 6월 16일
post-thumbnail

프로젝트를 진행하면서 공통 컴포넌트를 먼저 개발하게 되었다.그중에 React-toastify를 사용하여 사용자에게 메세지를 출력해주는 것을 구현 및 학습해보자 또한 어떠한 방식으로 처리해야 효율적으로 관리할 수 있는지 알아보자

React-toastify 설치

npm install react-toastify

ToastCotainer 속성

<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"
/>

속성 설명

속성명타입설명
positionToastPosition토스트가 화면의 어디에 나타날지 설정하는 것 ("top-right", "top-center", "bottom-right" 등)
autoClosenumber | false자동으로 닫히는 시간 (ms). false면 수동으로 닫아야 함.
hideProgressBarboolean진행 바 표시 여부.
newestOnTopboolean최신 알림을 위에 배치할지 여부.
closeOnClickboolean클릭 시 닫을 수 있는지 여부.
rtlboolean오른쪽에서 왼쪽 방향 표시 여부. (아랍어 등)
pauseOnFocusLossboolean창이 다른 곳으로 포커스 이동 시 일시정지.
draggableboolean드래그해서 닫기 가능 여부.
pauseOnHoverboolean마우스를 올리면 일시정지할지 여부.
theme"light" | "dark" | "colored"테마 색상
limitnumber화면에 표시될 수 있는 최대 토스트 개수 제한
containerIdstring여러 ToastContainer를 쓸 때 특정 ID로 구분
enableMultiContainerboolean여러 컨테이너를 동시에 쓸 수 있게 허용
transitionSlide, Zoom, Flip, Bounce토스트 나타나는 애니메이션
iconboolean | ReactNode아이콘을 커스터마이징하거나 제거 가능
toastStyleCSSProperties개별 토스트 박스의 인라인 스타일
bodyClassNamestring | function토스트 내부 body에 추가 클래스 적용
classNamestring | function컨테이너 자체에 클래스 적용

Context API를 이용해 공통 토스트 메세지

토스트 메시지를 만들때 그냥 사용도 가능하지만 효율성과 확장성을 좋게 하기 위하여 ContextAPI를 활용하여 중앙 집중화를 시켜 관리하면 좀 더 관리하기 쉽다.

ToastContext.tsx

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>
  );
};

useToast.ts

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;
};

LoginButton.tsx

import React from "react";
import { useToast } from "../hooks/useToast";

const LoginButton = () => {
  const { success, error } = useToast();

  const handleLogin = () => {
    // 로그인 성공 예시
    success("로그인 성공!");
    // 로그인 실패 예시
    // error("로그인 실패. 다시 시도해주세요.");
  };

  return <button onClick={handleLogin}>로그인</button>;
};
profile
나만의 기록장

0개의 댓글