Zustand 미들웨어와 일정 시간 후 상태 초기화 구현하기(localStorage)

2025. 2. 17. 22:15프론트엔드/REACT

728x90

Zustand 미들웨어와 일정 시간 후 상태 초기화 구현하기


🚀 Zustand를 이용한 애니메이션 상태 관리

React에서 글로벌 상태 관리를 할 때 가장 가볍고 사용하기 쉬운 상태 관리 라이브러리 중 하나가 Zustand입니다.
이 글에서는 zustand를 활용하여 애니메이션을 한 번만 실행하고, 일정 시간이 지나면 다시 실행되도록 구현하는 방법을 정리해보겠습니다.


✅ Zustand의 기본 개념

Zustand는 Redux보다 간결한 코드로 상태를 관리할 수 있는 라이브러리입니다.
기본적으로 Zustand는 메모리 기반 상태 관리이므로, 페이지가 새로고침되거나 이동하면 상태가 초기화됩니다.
이를 해결하기 위해 localStorage를 활용하여 상태를 유지하는 방법을 함께 적용할 것입니다.


🔹 Zustand 설치

Zustand를 설치하려면 프로젝트에서 다음 명령어를 실행하세요.

npm install zustand

이제 상태를 관리할 store.js 파일을 만들어서 애니메이션 상태를 관리해보겠습니다.


🔥 Zustand를 활용한 애니메이션 상태 관리

1️⃣ Zustand Store 생성 (store.js)

우리는 zustand의 persist 미들웨어를 사용하여 애니메이션 상태를 localStorage에 저장할 것입니다.
이렇게 하면 사용자가 페이지를 이동해도 애니메이션 상태가 유지됩니다.

import create from 'zustand';
import { persist } from 'zustand/middleware';

export const useAnimationStore = create(
  persist(
    (set) => ({
      showAnimation: true, // 애니메이션 초기값
      setShowAnimation: (value) => set({ showAnimation: value }),
    }),
    {
      name: 'animation-storage', // localStorage에 저장될 키 이름
      getStorage: () => localStorage, // localStorage를 사용하여 상태 유지
    }
  )
);

📝 코드 설명

  • persist 미들웨어를 사용하여 상태를 localStorage에 저장합니다.
  • showAnimation: 애니메이션을 실행할지 여부 (true면 실행, false면 실행 안 함)
  • setShowAnimation(value): 상태를 변경하는 함수

이제 zustand의 상태가 페이지 이동 후에도 유지됩니다.


🔹 2️⃣ Zustand 상태를 활용한 Unlogin 페이지

이제 zustand에서 애니메이션 상태를 가져와서 한 번만 실행하고, 일정 시간이 지나면 다시 실행되는 로직을 구현하겠습니다.

import React, { useState, useEffect } from 'react';
import Lottie from 'react-lottie-player';
import axios from 'axios';
import { useNavigate } from 'react-router-dom';
import './css/Unlogin.css';
import { useAnimationStore } from '../../store';

// Lottie 애니메이션 파일 경로
import startAnimation from '../../public/assets/lottie/start.json';

function Unlogin() {
  const [studentId, setStudentId] = useState('');
  const [password, setPassword] = useState('');
  const [showTooltip, setShowTooltip] = useState(false);
  const { showAnimation, setShowAnimation } = useAnimationStore(); // zustand 상태 사용
  const navigate = useNavigate();

  console.log("현재 showAnimation 상태:", showAnimation);

  // 3.5초 후 애니메이션 종료
  useEffect(() => {
    if (showAnimation) {
      const timer = setTimeout(() => {
        setShowAnimation(false); // 애니메이션 종료 후 상태 변경
      }, 3500);
      return () => clearTimeout(timer);
    }
  }, [showAnimation, setShowAnimation]);

  // 1시간(3600000ms) 후 다시 애니메이션 실행
  useEffect(() => {
    const lastShown = localStorage.getItem('lastAnimationTime');
    const currentTime = Date.now();

    if (!lastShown || currentTime - lastShown > 3600000) {
      setShowAnimation(true); // 1시간 지나면 다시 실행
      localStorage.setItem('lastAnimationTime', currentTime);
    }
  }, []);

  const handleLogin = async () => {
    if (!studentId || !password) {
      alert('학번과 비밀번호를 입력해주세요.');
      return;
    }

    const payload = { studentId, password };

    try {
      const response = await axios.post('https://csiereserve.store/api/login123', payload, {
        headers: { 'Content-Type': 'application/json' },
        withCredentials: true,
      });

      alert(`로그인 성공: ${response.data.message}`);
      navigate('/mainpage');
    } catch (error) {
      alert(`로그인 실패: ${error.response?.data?.message || error.message}`);
    }
  };

  return (
{/* 애니메이션이 실행되는 동안 showAnimation이 true일 때만 Lottie 컴포넌트 표시 */} {showAnimation ? ( ) : (
Logo
컴퓨터 정보공학부
회의실
setStudentId(e.target.value)} /> setPassword(e.target.value)} />
)}
  );
}

export default Unlogin;

✅ 3️⃣ 일정 시간이 지나면 다시 애니메이션 실행하기

useEffect(() => {
  const lastShown = localStorage.getItem('lastAnimationTime');
  const currentTime = Date.now();

  // 1시간(3600000ms) 지나면 다시 애니메이션 실행
  if (!lastShown || currentTime - lastShown > 3600000) {
    setShowAnimation(true);
    localStorage.setItem('lastAnimationTime', currentTime);
  }
}, []);

📝 코드 설명

  • localStorage.getItem('lastAnimationTime') → 마지막으로 애니메이션이 실행된 시간을 가져옴
  • currentTime - lastShown > 3600000 → 1시간(3600000ms)이 지나면 다시 애니메이션을 실행
  • setShowAnimation(true); → 애니메이션을 다시 실행하도록 설정

이제 애니메이션이 처음에 한 번만 실행되었다가, 1시간이 지나면 다시 실행됩니다! 🎉


🔹 최종 정리

  1. zustand의 persist 미들웨어를 활용하여 애니메이션 상태를 localStorage에 저장
  2. 한 번 실행 후 showAnimation 상태를 false로 변경하여 다시 실행되지 않도록 설정
  3. 1시간(3600000ms) 후 애니메이션이 다시 실행되도록 useEffect를 사용하여 관리
  4. 애니메이션이 실행되었는지 확인하기 위해 lastAnimationTime을 localStorage에 저장

🎯 결론

✅ zustand의 persist 미들웨어를 활용하면 페이지 이동 후에도 상태가 유지됨
✅ localStorage를 활용하여 일정 시간이 지나면 다시 애니메이션을 실행할 수 있음
✅ useEffect를 사용하여 애니메이션 실행 여부를 동적으로 관리 가능

이제 이 코드를 적용하면 애니메이션을 한 번만 실행하고, 일정 시간이 지나면 다시 실행되는 시스템이 완벽하게 동작합니다! 🚀

728x90