아 그거 뭐였지

[NextJS] react-tostify로 toast알림 구현하기 (.with styled-component, customHooks) 본문

Front-End

[NextJS] react-tostify로 toast알림 구현하기 (.with styled-component, customHooks)

승발자 2023. 4. 5. 12:13
728x90
반응형

너무 구린 alert 기본창

프로젝트도중 alert로 사용자에게 알림을 줬었는데 너무 예쁘지도 않고 확인버튼을 눌러야만 하는 것이 번거롭다고 생각했었다. 기왕 만드는 거 예쁜 알림창 하나 있었으면 좋겠다 싶어서 라이브러리를 찾아보았다.

 

라이브러리를 찾는 기준은 다음과 같았다.

 

  1. 커스텀훅으로 뺄 수 있을 것

  2. styled-component와 같이 사용해도 충돌이 일어나지 않을 것

 

여러 라이브러리들이 있었고 

 

아래 라이브러리를 사용했다가 ChakraUI가 styled-component의 컨테이너명과 겹치는 바람에 사용할 수 없게 되어

https://chakra-ui.com/

 

Chakra UI - A simple, modular and accessible component library that gives you the building blocks you need to build your React a

Simple, Modular and Accessible UI Components for your React Applications. Built with Styled System

chakra-ui.com

 

React-toastify라는 라이브러리를 채택하게 되었다.

https://fkhadra.github.io/react-toastify/introduction

 

React-toastify | React-Toastify

[![Financial Contributors on Open Collective](https://opencollective.com/react-toastify/all/badge.svg?label=financial+contributors)](https://opencollective.com/react-toastify) ![Travis (.org)](https://img.shields.io/travis/fkhadra/react-toastify.svg?label=

fkhadra.github.io

 

공식문서에서 알려주는 예시는 다음코드였다.

  import React from 'react';
  import { toast, ToastContainer } from 'react-toastify';
  import "react-toastify/dist/ReactToastify.css";


  function Example() {
    const notify = () => {
      toast("Default Notification !");

      toast.success("Success Notification !", {
        position: toast.POSITION.TOP_CENTER
      });

      toast.error("Error Notification !", {
        position: toast.POSITION.TOP_LEFT
      });

      toast.warn("Warning Notification !", {
        position: toast.POSITION.BOTTOM_LEFT
      });

      toast.info("Info Notification !", {
        position: toast.POSITION.BOTTOM_CENTER
      });

      toast("Custom Style Notification with css class!", {
        position: toast.POSITION.BOTTOM_RIGHT,
        className: 'foo-bar'
      });
    };

     return (
        <>
          <button onClick={notify}>Notify</button>;
          <ToastContainer />
        </>
      );
  }

유의해야 할 점은 ToastContainer를 추가시켜주지 않으면 보이지 않는다. toast 알림을 그려주는 곳이 해당 컨테이너인 것 같다.

사용하는 컴포넌트별로 ToastContainer를 추가해 주기에는 번거로우므로 최상위 루트 파일인 _app.tsx에 추가시켜 주었다.

 

toast함수를 사용하는 컴포넌트별로 import 해주고 css도 불러오고 하는 과정이 굉장히 귀찮기 때문에

커스텀훅으로 분리해 보자.

 

useToast

import { toast, ToastOptions, ToastPosition } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';

type ToastType = 'info' | 'warn' | 'success' | 'error';

interface ToastProps {
  showToast: (type: ToastType, message: string, options?: ToastOptions) => void;
}

const useToast = (): ToastProps => {
  /**
   *
   * @param {ToastType} type 토스트 타입을 정의해줍니다. info, warn, success, error중 선택합니다.
   * @param {string} message 사용자에게 보여줄 메세지를 입력합니다.
   * @param {ToastOptions} options 토스트의 옵션을 선택합니다.
   */
  const showToast = (
    type: ToastType,
    message: string,
    options: ToastOptions = { icon: null }
  ) => {
    toast[type](message, options);
  };
  return {
    showToast,
  };
};

export default useToast;

useToast라는 커스텀훅을 만들고 showToast함수를 정의한다. showToast는 type, message, options를 파라미터로 받는다.

type에는 info, success와 같이 toast.info 메서드들을 사용할 수 있는 타입을 받기 위해 파라미터로 선언하였다.

나머지 message는 알림을 띄울 텍스트와 position이나 icon을 설정할 수 있는 옵션들을 객체로 받는다.

 

옵션이 굉장히 많아서 사용하고자 하는 옵션을 공식문서에서 찾아쓰면 될 것 같다.

 

https://fkhadra.github.io/react-toastify/api/toast
 

toast | React-Toastify

## Props

fkhadra.github.io

 

본인이 생각했을 때 자주 쓸 거 같은 옵션들은

  • position : toast 알림 위치를 정해준다 bottom-center, top-center 등 정해져 있는 스트링이 있다.
  • icon: 아이콘을 변경할 수 있다. 아이콘 경로를 적어주거나 img태그를 줄수도 있다. ""을하면 아이콘을 없앨 수 있다.
  • closeButton: 알림 창 우측상단에 X표시를 true false로 보여주고 안 보여줄 수 있다

이렇게 세 가지 정도 있는데 나머지는 찾아보도록 하자.

 

showToast를 사용하는 컴포넌트에서의 예시이다.

ExampleComponent

import useToast from '@src/hooks/useToast'
import { ToastContainer } from 'react-toastify';

const { showToast } = useToast();

return (
  <button onClick={()=>showToast('info','클립보드가 복사되었습니다.',{position:"bottom-center",icon:"",closeButton:false})}>클릭</button>
  
  //최상위 파일에서 선언해주었으면 선언해주지않아도됨
  <ToastContainer />
)

showToast에 원하는 속성값을 넣어주면 된다.

 

본인은 ToastContainer도 styled-copmonent로 스타일을 커스텀하기 위해 따로 컴포넌트를 분리하였다.

CMToast

import { ToastContainer } from 'react-toastify';
import 'react-toastify/dist/ReactToastify.css';
import styled from 'styled-components';

const CMToast = () => {
  return <Toast autoClose={1000} hideProgressBar />;
};

const Toast = styled(ToastContainer)`
  .Toastify__toast--success {
    background-color: #4caf50;
    color: #fff;
  }
  .Toastify__toast--error {
    background-color: #f44336;
    color: #fff;
  }
  .Toastify__toast--warning {
    background-color: #ff9800;
    color: #fff;
  }
  .Toastify__toast--info {
    background-color: ${({ theme }) => theme.commonColor.pink004};
    color: #fff;
  }
`;

export default CMToast;

사용법은 굉장히 간단하다. 각각의 타입 이름에 따라서 변경하고 싶은 대로 값을 변경해 주면 된다.

. Toastify__toast 뒤에 오는 --success 이 부분이 타입명이다. 

 

aucoClose와 hideProgressBar는 ToastContainer의 옵션이다. autoClose={1000}은 1초 뒤 자동으로 닫으라는 의미이고

hideProgressBar는 자동으로 닫히는 시간을 원래 표시해 주는데 그것을 가려주는 옵션이다.

 

styled-component를 사용해서 스타일을 변경하는 것까지 보여주었다. 공식문서를 살펴보면 해당 4개의 타입 외에

아예 커스텀할 수도 있는 방법을 제시해 주는데 아직은 4개의 타입으로도 충분해서 추후에 필요해지면 적용해볼계획이다.

 

CMToast로 분리하였지만 showToast안에서 return으로 ToastContainer를 리턴해주면 어떨까 싶기도 하고.. 그러기엔 hook이니 component로 분리하는게 맞는가 싶다.

 

여하튼 저렇게 완성된 toast 알림을 보고 글을 마무리하도록 하겠다.

 

 

 

728x90
반응형
Comments