⭐️ Today's summary
현재 프로젝트 7일차에 게시글쪽 페이지를 만들고 있는데, 게시글을 누를때마다 조회수를 1증가 시키고싶었다.
오늘은 게시글을 누를때마다 조회수가 1 증가하도록 만들어 보겠다.
⭐️ Problem
[ BoardDetailPage.jsx ]
import React from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Button, Content, DetailWrapper, InfoBox, InfoItem, Title } from '../components/styled/Board.js';
import boardStore from '../store/boardStore';
import { FaRegFileAlt } from 'react-icons/fa';
import { useEffect } from 'react';
import userInfoStore from '../store/userInfoStore.js';
import { Notice } from '../components/styled/Notice.js';
const BoardDetailPage = () => {
const { no } = useParams();
const navigate = useNavigate();
const { boardList, getBoardList } = boardStore();
const { userInfo } = userInfoStore();
useEffect(() => {
getBoardList();
}, []);
const boardDetail = boardList.find((board) => board.no === parseInt(no));
if (!boardDetail) return <div>게시글을 찾을 수 없습니다.</div>;
return userInfo ? (
<DetailWrapper>
<Title>
<FaRegFileAlt style={{ marginRight: '10px', verticalAlign: 'middle', marginBottom: '5px' }} />
게시글 상세보기
</Title>
<h2 style={{ fontSize: '28px', color: 'white', marginBottom: '20px' }}>{boardDetail.title}</h2>
<InfoBox>
<InfoItem>
<strong>글 번호</strong> {boardDetail.no}
</InfoItem>
<InfoItem>
<strong>작성자</strong> {boardDetail.writer}
</InfoItem>
<InfoItem>
<strong>작성일</strong> {boardDetail.date}
</InfoItem>
<InfoItem>
<strong>조회수</strong> {boardDetail.views}
</InfoItem>
</InfoBox>
<Content>{boardDetail.content}</Content>
<Button onClick={() => navigate('/boardPage')}>목록으로</Button>
</DetailWrapper>
) : (
<Notice>로그인 정보가 없습니다.</Notice>
);
};
export default BoardDetailPage;
현재 코드에서 getBoardList()는 boardStore에서 가져오고 있다.
하지만 어느 시점에 조회수를 1 증가 시켜줘야하는지 감이 잡히지 않았다.
[ boardStore.js ]
import axios from 'axios';
import { create } from 'zustand';
const boardStore = create((set) => ({
boardList: [],
totalCount: null,
getBoardList: async () => {
try {
const res = await axios.get(`http://localhost:3001/board`);
if (res.status === 200) {
const sortedData = res.data.sort((a, b) => b.no - a.no); // no 기준 내림 차순 정렬
set({ boardList: sortedData, totalCount: res.data.length });
}
} catch (error) {
console.error('게시판 불러오기 실패:', error);
}
},
}));
export default boardStore;
boardStore.js는 위와같이 되어있는데, 저기서 getBoardList()는 게시글만 가져오고, 내림 차순으로 정렬을 해주는
코드이다.
현재 조회수를 1 증가할려면 함수를 하나 더 만들어야하는지, 아니면 getBoardList()를 바꿔서 만들어야하는지 어려웠다.
⭐️ Try
[ BoardDetailPage.jsx ]
import React from 'react';
import { useParams, useNavigate } from 'react-router-dom';
import { Button, Content, DetailWrapper, InfoBox, InfoItem, Title } from '../components/styled/Board.js';
import boardStore from '../store/boardStore';
import { FaRegFileAlt } from 'react-icons/fa';
import { useEffect } from 'react';
import userInfoStore from '../store/userInfoStore.js';
import { Notice } from '../components/styled/Notice.js';
const BoardDetailPage = () => {
const { no } = useParams();
const navigate = useNavigate();
const { boardList, getBoardList, viewsUp } = boardStore();
const { userInfo } = userInfoStore();
useEffect(() => {
const updateView = async () => {
await viewsUp(no); // 조회수 먼저 증가
await getBoardList(); // 최신 목록 가져오기 (조회수 반영됨)
};
updateView();
}, []);
const boardDetail = boardList.find((board) => board.no === parseInt(no));
if (!boardDetail) return <div>게시글을 찾을 수 없습니다.</div>;
return userInfo ? (
<DetailWrapper>
<Title>
<FaRegFileAlt style={{ marginRight: '10px', verticalAlign: 'middle', marginBottom: '5px' }} />
게시글 상세보기
</Title>
<h2 style={{ fontSize: '28px', color: 'white', marginBottom: '20px' }}>{boardDetail.title}</h2>
<InfoBox>
<InfoItem>
<strong>글 번호</strong> {boardDetail.no}
</InfoItem>
<InfoItem>
<strong>작성자</strong> {boardDetail.writer}
</InfoItem>
<InfoItem>
<strong>작성일</strong> {boardDetail.date}
</InfoItem>
<InfoItem>
<strong>조회수</strong> {boardDetail.views}
</InfoItem>
</InfoBox>
<Content>{boardDetail.content}</Content>
<Button onClick={() => navigate('/boardPage')}>목록으로</Button>
</DetailWrapper>
) : (
<Notice>로그인 정보가 없습니다.</Notice>
);
};
export default BoardDetailPage;
[ boardStore.js ]
import { Co2Sharp } from '@mui/icons-material';
import axios from 'axios';
import { create } from 'zustand';
const boardStore = create((set) => ({
boardList: [],
totalCount: null,
getBoardList: async () => {
try {
const res = await axios.get(`http://localhost:3001/board`);
if (res.status === 200) {
const sortedData = res.data.sort((a, b) => b.no - a.no); // no 기준 내림 차순 정렬
set({ boardList: sortedData, totalCount: res.data.length });
}
} catch (error) {
console.error('게시판 불러오기 실패:', error);
}
},
viewsUp: async (boardNo) => {
try {
// 게시글 조회
const res = await axios.get(`http://localhost:3001/board?no=${boardNo}`);
const target = res.data[0]; // 첫 번째 게시글 객체 -> get은 객체 배열로 주기 때문에 따로 꺼내기
if (target) {
await axios.patch(`http://localhost:3001/board/${target.id}`, {
views: target.views + 1,
});
}
} catch (error) {
console.error('게시판 조회수 증가 실패:', error);
}
},
}));
export default boardStore;
내가 생각해낸 방법은 viewsUp이라는 함수를 store에 만들고 userEffect를통해서 viewsUp()이 실행완료된 후에
getBoardList()를 가져오게 해서 조회수를 증가시키게 만들었다.
조회수 증가시키는것이 생각보다 까다로운거같았다. 백앤드로만 조회수 증가시키는 방식과 코드면에서 많이 달라서
어려움이 있었지만 잘 해결했다.
'Weekly TIL' 카테고리의 다른 글
Weekly TIL - Day 26 (0) | 2025.05.10 |
---|---|
Weekly TIL - Day 25 (0) | 2025.05.09 |
Weekly TIL - Day 22 (0) | 2025.05.06 |
Weekly TIL - Day 21 (0) | 2025.05.05 |
Weekly TIL - Day 20 (0) | 2025.05.04 |