2025. 2. 17. 22:15ㆍ프론트엔드/REACT
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 (
회의실
);
}
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시간이 지나면 다시 실행됩니다! 🎉
🔹 최종 정리
- zustand의 persist 미들웨어를 활용하여 애니메이션 상태를 localStorage에 저장
- 한 번 실행 후 showAnimation 상태를 false로 변경하여 다시 실행되지 않도록 설정
- 1시간(3600000ms) 후 애니메이션이 다시 실행되도록 useEffect를 사용하여 관리
- 애니메이션이 실행되었는지 확인하기 위해 lastAnimationTime을 localStorage에 저장
🎯 결론
✅ zustand의 persist 미들웨어를 활용하면 페이지 이동 후에도 상태가 유지됨
✅ localStorage를 활용하여 일정 시간이 지나면 다시 애니메이션을 실행할 수 있음
✅ useEffect를 사용하여 애니메이션 실행 여부를 동적으로 관리 가능
이제 이 코드를 적용하면 애니메이션을 한 번만 실행하고, 일정 시간이 지나면 다시 실행되는 시스템이 완벽하게 동작합니다! 🚀
'프론트엔드 > REACT' 카테고리의 다른 글
| CSS로 예약 불가 슬롯에 X자 표시하기 x배너 꾸미기 [React] (2) | 2025.02.20 |
|---|---|
| Framer Motion: React에서 강력한 애니메이션 라이브러리 (4) | 2025.02.17 |
| React 관심사 선택 모달 개선하기 (3) | 2025.02.17 |
| React 모달에서 입력값을 "수정하기" 버튼을 눌러야 반영되도록 하기 (3) | 2025.02.17 |
| React에서 관심사(취미) 선택 모달 구현하기 (6) | 2025.02.16 |