Next.js에서 SSE(Server-Sent Events)와 Zustand를 활용한 실시간 알림 배지 시스템 구현
- SSE(Server-Sent Events)와 Zustand를 활용하여 실시간 알림 배지 표시
- 특정 이벤트가 발생할 때 클라이언트가 알림을 받고 UI를 자동 업데이트하는 방법
- 서버에서 주기적으로 새로운 알림을 전송하고, 클라이언트에서 알림 개수를 표시하는 UI 구현
npm install zustand
store/useNotificationStore.js (Zustand 전역 상태)
import { create } from 'zustand';
const useNotificationStore = create((set) => ({
notifications: [],
unreadCount: 0,
addNotification: (notif) =>
set((state) => ({
notifications: [...state.notifications, notif],
unreadCount: state.unreadCount + 1,
})),
markAllRead: () => set({ unreadCount: 0 }),
}));
export default useNotificationStore;
pages/api/notifications.js (SSE 알림 API)
export default function handler(req, res) {
res.setHeader('Content-Type', 'text/event-stream');
res.setHeader('Cache-Control', 'no-cache');
res.setHeader('Connection', 'keep-alive');
const sendNotification = (message) => {
res.write(`data: ${JSON.stringify({ message, time: new Date().toLocaleTimeString() })}\n\n`);
};
sendNotification('새로운 알림 시스템이 시작되었습니다.');
const interval = setInterval(() => {
sendNotification(`새로운 이벤트 발생!`);
}, 7000);
req.on('close', () => {
clearInterval(interval);
});
}
components/NotificationBadge.js (알림 배지 UI)
'use client';
import { useEffect } from 'react';
import useNotificationStore from '../store/useNotificationStore';
export default function NotificationBadge() {
const { unreadCount, addNotification, markAllRead } = useNotificationStore();
useEffect(() => {
const eventSource = new EventSource('/api/notifications');
eventSource.onmessage = (event) => {
addNotification(JSON.parse(event.data));
};
return () => eventSource.close();
}, [addNotification]);
return (
<div>
<h2>실시간 알림 배지</h2>
<button onClick={markAllRead}>
알림 보기 {unreadCount > 0 && <span>({unreadCount})</span>}
</button>
</div>
);
}
components/NotificationList.js (실시간 알림 UI)
'use client';
import useNotificationStore from '../store/useNotificationStore';
export default function NotificationList() {
const notifications = useNotificationStore((state) => state.notifications);
return (
<div>
<h2>알림 목록</h2>
<ul>
{notifications.map((notif, index) => (
<li key={index}>{notif.message} ({notif.time})</li>
))}
</ul>
</div>
);
}
app/page.js
import NotificationBadge from '../components/NotificationBadge';
import NotificationList from '../components/NotificationList';
export default function Home() {
return (
<div>
<NotificationBadge />
<NotificationList />
</div>
);
}
SSE와 Zustand를 활용하면 실시간 알림 배지 및 알림 UI를 쉽게 구축 가능