react-toastify 라이브러리를 활용하여 Next.js 프로젝트에서 커스텀 토스트 알림 컴포넌트를 만드는 방법을 설명합니다. 이 컴포넌트는 프로젝트 전반에 걸쳐 일관된 스타일과 옵션을 가진 토스트 알림을 사용할 수 있도록 재사용 가능하게 설계되었습니다.
npm url: https://www.npmjs.com/package/react-toastify
먼저, 커스텀 토스트 컴포넌트를 위한 폴더 구조는 다음과 같습니다:
/toast
├── CustomToastContainer.tsx
├── index.ts
├── toast.tsx
└── toastStyle.ts
각 파일의 역할은 다음과 같습니다:
CustomToastContainer.tsx
: 기본 설정으로 커스터마이징된 토스트 컨테이너를 생성합니다.toast.tsx
: 기본 및 에러 토스트와 같은 다양한 유형의 토스트를 표시하는 유틸리티 함수를 포함합니다.toastStyle.ts
: styled-components를 사용하여 토스트의 스타일을 정의합니다.index.ts
: 이 파일은 일반적으로 폴더 내 모든 함수와 컴포넌트를 내보내 다른 곳에서 쉽게 가져올 수 있도록 사용됩니다.CustomToastContainer.tsx 파일은 기본 옵션으로 토스트 컨테이너를 설정하는 역할을 합니다:
import { ToastContainerProps } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import * as Style from './toastStyle';
interface ToastPropsType extends ToastContainerProps {}
function CustomToastContainer(props: ToastPropsType) {
const defaultToastOption: ToastContainerProps = {
position: 'bottom-left',
hideProgressBar: true,
closeOnClick: true,
closeButton: false,
};
return <Style.Toast {...defaultToastOption} {...props} />;
}
export default CustomToastContainer;
react-toastify/dist/ReactToastify.css Import
: react-toastify 라이브러리에서 제공하는 기본 스타일을 사용하기 위해 CSS 파일을 가져옵니다. 이 스타일 시트는 기본적인 토스트 알림의 모양과 느낌을 정의하며, 별도의 커스터마이징 없이도 사용이 가능합니다.ToastContainerProps 인터페이스
: react-toastify의 ToastContainerProps 인터페이스를 확장하여 타입 안전성을 확보합니다.defaultToastOption 객체
: 토스트 컨테이너의 기본 설정을 포함하고 있습니다. (예: 위치, 프로그레스 바 숨기기, 클릭 시 닫기 등)<Style.Toast>
: 기본 ToastContainer를 커스텀 스타일로 감싸는 styled-components 컴포넌트입니다.모든 페이지에서 토스트를 호출하기 위해 CustomToastContainer컴포넌트를 _app.tsx 파일에 추가합니다.
import CustomToastContainer from '@/components/toast/CustomToastContainer';
function MyApp({ Component, pageProps }) {
return (
<>
<Component {...pageProps} />
<CustomToastContainer />
</>
);
}
export default MyApp;
toastStyle.ts
파일에서는 styled-components를 사용하여 토스트의 스타일을 정의합니다.
import { ToastContainer } from 'react-toastify';
import hexToRgba from '@/utils/hexToRgba';
import styled, { css } from 'styled-components';
const Toast = styled(ToastContainer)`
${({ theme }) => {
const { colors, fonts, media, variable } = theme;
return css`
z-index: 99;
.Toastify__toast {
// ...
}
.Toastify__toast-body {
// ...
}
&.Toastify__toast-container--top-center {
left: 50%;
transform: translateX(-50%);
}
&.Toastify__toast-container--top-center,
&.Toastify__toast-container--top-left,
&.Toastify__toast-container--top-right {
top: calc(${variable['$mobile-header-height']} + 10px);
.Toastify__toast {
margin-top: 5px;
}
${media.desktop} {
top: ${variable['$desktop-header-height']};
}
}
`;
}}
`;
.Toastify__toast
: 이 클래스는 각각의 토스트 알림을 나타냅니다. react-toastify가 생성하는 기본적인 토스트 요소에 적용됩니다.
.Toastify__toast-body
: 이 클래스는 토스트 알림 내의 본문(content) 부분을 나타냅니다. 메시지나 텍스트가 위치하는 곳 입니다.
&.Toastify__toast-container--top-center, &.Toastify__toast-container--top-left, &.Toastify__toast-container--top-right
: 이 클래스들은 토스트 컨테이너의 위치를 정의하는 클래스들이며, 이 코드에서는 top-center, top-left, top-right 위치에 있는 토스트 컨테이너의 top위치를 설정하고 있습니다.
toast.tsx 파일에는 showToast, defaultToast와 errorToast라는 세 가지 유틸리티 함수가 포함되어 있으며, 각각은 다른 유형의 토스트를 표시하는 역할을 합니다.
import { ToastContainerProps, toast } from 'react-toastify';
function showToast(message: string, hasCloseBtn: boolean, options?: ToastContainerProps, icon?: JSX.Element) {
const toastId = toast(message, {
...options,
icon: icon || undefined,
autoClose: hasCloseBtn ? false : 2000,
closeButton: hasCloseBtn ? (
<Style.CloseButton>
<CloseIcon />
</Style.CloseButton>
) : undefined,
});
return toastId;
}
// 기본 토스트를 호출하는 함수
function defaultToast(message: string, hasCloseBtn: boolean, options?: ToastContainerProps) {
return showToast(message, hasCloseBtn, options);
}
// 에러 토스트를 호출하는 함수
function errorToast(message: string, hasCloseBtn: boolean, options?: ToastContainerProps) {
return showToast(message, hasCloseBtn, options, <ErrorIcon />);
}
export { showToast, defaultToast, errorToast };
showToast 함수
: 이 함수는 공통적인 토스트 로직을 처리합니다. 메시지, 닫기 버튼 여부, 추가 옵션, 그리고 선택적인 아이콘을 인자로 받습니다.defaultToast 함수
: showToast 함수를 호출하여 기본 토스트를 생성합니다. 아이콘이 필요하지 않기 때문에 icon 인자를 전달하지 않습니다.errorToast 함수
: 에러 토스트를 생성할 때는 showToast 함수에 ErrorIcon을 icon 인자로 전달합니다.import { defaultToast, errorToast } from '@/components/toast';
function ErrorExampleComponent() {
const handleErrorClick = () => {
defaultToast('This is a default toast message', true);
errorToast('This is a error toast message', false, {
position: 'top-left',
});
};
return (
<div>
<button onClick={handleErrorClick}>Show Error Toast</button>
</div>
);
}
export default ErrorExampleComponent;