[React] 실시간 검색 - debouncing 기능 구현하기
[React] 실시간 검색 - debouncing 기능 구현하기
[React, Express] 서버 구현 및 데이터베이스 연결하기(REST API) [React, Express] 서버 구현 및 데이터베이스 연결하기(REST API)[EZ_Scheduler] - [React] 로그인 페이지 스타일링 [React] 로그인 페이지 스타일링📌
juyear-coding.tistory.com
이전 글 읽으러 가기! (실시간 검색 기능)
🚩소개
안녕하세요! 대학생 개발자 주이어입니다! 오늘은 React에서 사용자별 알림 기능을 구현하는 방법에 대해서 정리해보려고 합니다!
Notification System, 즉 알림 기능은 우리가 평소에 자주 사용하는 기능입니다. 유튜브에 새로운 영상이 올라오거나, 인스타그램에 새로운 게시글이 올라왔을 때 알려주는 알림이 이에 해당됩니다.
알림 시스템의 기본 흐름은 아래와 같습니다.
새로운 이벤트 -> 알림 추가 -> 사용자 상호작용 -> 알림 삭제
하지만 이런 시스템을 여러 사용자가 동시에 사용하는 서비스에 적용하려면 사용자마다 알림 상태를 다르게 저장하고 처리해줘야 한다는 점에서 조금 더 복잡해집니다.
💻 Notification System 구현하기
📍 클라이언트 (App.jsx)
useEffect(() => {
axios.get(`http://localhost:5000/notification/${userId}`).then((res) => {
setNotiData(res.data);
console.log(res.data);
});
}, [changeNoti]);
먼저 App.jsx에서 위와 같이 userId를 이용하여 현재 사용자가 읽지 않은 알림은 서버에서 받아오도록 작성해주었습니다.
(useEffect 사용, 변경시 실행하도록 설정)
로그인 하기 전에는 현재 사용자가 누구인지 알 수 없으므로, 로그인 할 때, changeNoti State 변수 값을 바꿔 값을 가져오도록 해주었습니다.
📍 클라이언트 (Sidebar.jsx)
<div className="section" onClick={onClickNoti}>
<img src={heartIcon} alt="Info" width="25" />
<p>알림</p>
{notiData && notiData.length > 0 && <div className="notiDot"></div>}
</div>
읽지 않은 알림이 있을 경우 알림 버튼에 빨간 점(.notiDot)을 표시해 알림이 있다는 것을 알려줄 수 있도록 만들었습니다.
const onClickNoti = () => {
setIsOpenNoti(!isOpenNoti);
axios
.post("http://localhost:5000/readNoti", {
userId,
notiIds: notiData.map((item) => item.id),
})
.then((res) => {
if (res.data.success) {
console.log("알림 읽음.");
}
});
};
알림 버튼 클릭 시, 현재 읽지 않은 알림들의 ID 배열을 서버에 전송하고, 서버에서는 해당 알림들을 읽은 상태로 처리해줄 수 있도록 만들어 주었습니다.
🛠️ 서버 (server.js)
✔️ 읽지 않은 알림 가져오기
app.get("/notification/:userId", async (req, res) => {
const userId = req.params.userId;
const query = `
SELECT * FROM file_info f
WHERE f.userId != ?
AND NOT EXISTS (
SELECT 1 FROM notification_reads r
WHERE r.post_id = f.id AND r.reader_id = ?
)
ORDER BY f.created_at DESC
`;
try {
const [result] = await db.execute(query, [userId, userId]);
res.json(result);
} catch (err) {
res.json({ message: err });
}
});
file_info 테이블에서 다른 사용자가 업로드한 게시글 중, 해당 사용자가 읽지 않은 글만 필터링 해서 가져와 주었습니다.
그 후, notifications_reads 테이블과 NOX EXISTS 조건을 이용해 읽은 기록이 없는 글만 추출해 주었습니다.
(서버는 node + express, DB는 MySQL 사용해서 만들었습니다.)
✔️ 알림 읽음 처리
app.post("/readNoti", async (req, res) => {
const { userId, notiIds } = req.body;
const query = `
INSERT IGNORE INTO notification_reads (post_id, reader_id)
VALUES (?, ?)
`;
try {
notiIds.map(async (id) => {
await db.execute(query, [id, userId]);
});
res.json({ success: true });
} catch (err) {
res.json({ message: err });
}
});
클라이언트로부터 받은 알림 ID 배열을 기반으로, 각 알림을 읽음 처리 해주었습니다. (db에 데이터 추가로 처리)
INSERT IGNORE를 사용해서 중복된 값이 있을 경우 무시하도록 처리 해주었습니다.
💻 구현 화면
위 두개의 사진을 보면 읽지 않은 알림이 있을 경우 빨간 점이 표시되고,
알림을 읽을 이후에는 빨간 점이 사라지는 것을 알 수 있습니다.
알림 버튼을 클릭하면 위와 같이 알림 정보가 표시되는 알 수 있습니다.
한번 읽은 후 새로고침하면 더 이상 알림 정보가 나오지 않도록 해주었습니다.
😊 마무리
지금까지 React와 Node.js로 Notification System, 알림 기능을 구현하는 방법에 대해서 정리해 보았습니다.
처음 제가 이 기능을 만들 때만 해도, 단순히 알림 데이터를 보여주기만 하면 될 줄 알았는데, 사용자별로 알림 상태를 따로 관리해야한다는 점에서 SQL 쿼리 작성이 꽤 까다로웠습니다.
특히 INSERT IGNORE와 NOT EXISTS와 같은 조건을 적절히 활용해야 제대로 된 알림 필터링이 가능하다는 걸 배웠습니다.
이 글을 읽는 분들도 한 번씩 구현해보시고, 프로젝트에 적용해보시길 바랍니다! 알림 기능은 자주 사용되는 기술이니 원리와 구조에 대해서도 공부하시는 것을 추천드립니다!
KYT CODING COMMUNITY Discord 서버에 가입하세요!
Discord에서 KYT CODING COMMUNITY 커뮤니티를 확인하세요. 20명과 어울리며 무료 음성 및 텍스트 채팅을 즐기세요.
discord.com
KYT CODING COMMUNITY 가입하기!
'[React]' 카테고리의 다른 글
[React] 실시간 검색 - debouncing 기능 구현하기 (0) | 2025.04.19 |
---|