Dandy Now!
  • [React.js] React-Toastify 적용
    2024년 02월 02일 17시 52분 32초에 업로드 된 글입니다.
    작성자: DandyNow
    728x90
    반응형

    1. React-Toastify 설치

    1) 설치

     https://www.npmjs.com/package/react-toastify#react-toastify

    npm install --save react-toastify

     

    2) 추가 설치

    사용자 정의 애니메이션(Define a custom enter and exit animation)을 적용하고자 한다면 설치하면 된다.

    React-Toastify 공식 문서: https://fkhadra.github.io/react-toastify/custom-animation

    Animate.css 공식 문서: https://animate.style/

    npm install animate.css --save

     

    3. React-Toastify 적용예

    📌 app.js

    import "./App.css";
    import { useEffect, useState } from "react";
    
    // 토스트 관련 import
    import "animate.css/animate.min.css"; // 사용자 정의 애니메이션
    import "react-toastify/dist/ReactToastify.css"; // React-Toastify
    import { ToastContainer, toast, cssTransition } from "react-toastify"; // 사용할 컴포넌트
    
    // 기본 react-toastify 스타일이 아닌 커스텀 스타일을 사용하고자 Msg라는 컴포넌트를 생성함
    function Msg({ title, content }) {
      return (
        <div
          onClick={() => {
            console.log("click!");
          }}
          style={{ cursor: "pointer" }}
        >
          <div className="msg-container">
            <p className="toast-ap-level">{title}</p>
            <p className="toast-ap-level">|</p>
            <p className="toast-ap-name">{content}</p>
          </div>
        </div>
      );
    }
    
    function App() {
      /*
      토스트 작동 테스트를 위한 코드
      */
      const [clickCount, setClickCount] = useState(1);
    
      const handleClickCount = () => {
        setClickCount((prev) => prev + 1);
        console.log(clickCount);
      };
    
      const data = [
        { title: "title1", content: "content1" },
        { title: "title2", content: "content2" },
        { title: "title3", content: "content3" },
      ];
    
      /*
      토스트 코드
      1) 커스텀-바운스-애니메이션 적용
      2) 새로운 토스트 팝업시 기존 토스트 제거
      3) 커스텀 아이콘 적용
      */
      // 커스텀-바운스-애니메이션
      // https://fkhadra.github.io/react-toastify/custom-animation
      const bounce = cssTransition({
        enter: "animate__animated animate__bounceIn",
        exit: "animate__animated animate__bounceOut",
      });
    
      useEffect(() => {
        // 기존 토스트를 모두 제거하는 방식이 아닌, 동일 정보를 가진 토스트가 있다면 duplicate를 막는 방식을 적용할 수도 있다.
        // https://fkhadra.github.io/react-toastify/prevent-duplicate
        toast.dismiss(); // 기존 토스트 모두 제거
        data.forEach((el) => {
          const { title, content } = el;
          toast(<Msg title={title} content={content} />, {
            transition: bounce, // 커스텀 애니메이션(Define a custom enter and exit animation) 속성
            // 커스텀 아이콘 적용
            // https://fkhadra.github.io/react-toastify/icons#custom-icons
            icon: ({ theme, type }) => (
              <svg
                width="20"
                height="20"
                viewBox="0 0 24 26"
                fill="none"
                xmlns="http://www.w3.org/2000/svg"
              >
                <path
                  d="M1.55614 23.4V15.6C1.55614 12.8417 2.65647 10.1965 4.61507 8.24609C6.57368 6.29571 9.23011 5.2 12 5.2C14.7699 5.2 17.4263 6.29571 19.3849 8.24609C21.3435 10.1965 22.4439 12.8417 22.4439 15.6V23.4H23.7493V26H0.250653V23.4H1.55614ZM4.1671 23.4H19.8329V15.6C19.8329 13.5313 19.0077 11.5474 17.5387 10.0846C16.0697 8.62178 14.0774 7.8 12 7.8C9.92259 7.8 7.93026 8.62178 6.46131 10.0846C4.99235 11.5474 4.1671 13.5313 4.1671 15.6V23.4ZM10.6945 0H13.3055V3.9H10.6945V0ZM22.154 3.6504L24 5.4886L21.2324 8.2459L19.3851 6.4077L22.154 3.6504ZM0 5.4886L1.84595 3.6504L4.61488 6.4064L2.77023 8.2472L0 5.4886ZM5.47259 15.6C5.47259 13.8761 6.16029 12.2228 7.38442 11.0038C8.60855 9.78482 10.2688 9.1 12 9.1V11.7C10.9613 11.7 9.96513 12.1109 9.23065 12.8423C8.49618 13.5737 8.08355 14.5657 8.08355 15.6H5.47259Z"
                  fill="white"
                />
              </svg>
            ),
            theme: "colored",
            position: "top-center",
            autoClose: false,
            className: "toast-color-level-danger", // 커스텀 스타일
          });
        });
      }, [clickCount]);
    
      return (
        <div style={{ display: "flex", height: "100dvh" }}>
          {/* 화면 중앙의 "클릭!" 버튼 클릭시 토스트 3개 팝업됨 */}
          <div style={{ margin: "auto" }}>
            <button
              onClick={() => {
                handleClickCount();
              }}
            >
              클릭!
            </button>
          </div>
          <ToastContainer />
        </div>
      );
    }
    
    export default App;

     

    📌 app.css

    .msg-container {
      display: flex;
      space-between: center;
    }
    
    .toast-ap-level {
      font-size: 1.5rem;
      margin-right: 1.5rem;
    }
    
    .toast-ap-name {
      font-weight: bolder;
      font-size: 1.5rem;
      margin-right: 1.5rem;
    }
    
    .toast-ap-count {
      font-size: 1.5rem;
    }
    
    .Toastify__toast-container {
      width: calc(50%) !important;
    }
    
    .toast-color-level-danger {
      --danger: #f94144;
      background: var(--danger) !important;
      color: #fff !important;
    }

     

    728x90
    반응형
    댓글