React에서 강좌 리뷰 버튼 활성화 처리하기: some() vs Map

SayBridge 프로젝트를 진행하면서, 강좌별로 “내가 이미 리뷰를 작성했는가?”를 확인하여 리뷰 작성 버튼을 활성화하거나 비활성화하는 기능이 필요했다.


 처음에는 로직을 처리하는 부분이라 서버에서 해당 코스에 리뷰가 있는 지를 확인하여 각 코스마다 리뷰 여부를 확인 요청을 보내려했는데 그럴 경우 요청이 코스 수만큼 늘어나 데이터가 많아지면 서버 부하가 심해질 것 같았다. 

 기존 MyPage 로드 시 유저가 수강중인 강좌, 작성한 리뷰를 불러오는데, 이때 저장한 강좌 및 리뷰 정보를 이용하여 프론트에서 해당 기능을 구현하기로 했다. 

 

 처음에는 단순하게 .some()를 사용해 각 코스마다 리뷰를 찾는 방식으로 구현하였다.

const hasReview = reviews.some(review => review.courseId === course.id);

 

 이렇게 하면 리뷰 배열의 길이가 n, 코스 배열의 길이가 m일 때, 최악의 경우 코스 하나당 최대 n번 순회(=선형 탐색)해야한다. 즉, 모든 코스를 렌더링하는 과정에서 총 m * n만큼 탐색이 이루어질 수 있다.  

 이 방식은 데이터가 작을 때는 빠르고 간단하지만, 리뷰나 코스가 아주 많아지면 비효율적일 수 있다.

 

이를 해결하기 위해,  데이터 로드 시점에 한 번 리뷰 데이터를 순회해서 “courseId -> 리뷰 데이터” 형태의 맵을 만든 다음, 렌더링에서는 이 맵에 O(1)에 접근하는 방식을 사용했다.

const [reviews, setReviews] = useState([]);
const [reviewMap, setReviewMap] = useState({});
useEffect(() => {
const newMap = {};
reviews.forEach(review => {
newMap[review.courseId] = review;
});
setReviewMap(newMap);
}, [reviews]);
const hasReview = !!reviewMap[course.id];

 

 reviews.forEach(...)로 한 번만 순회하여 Map 생성 시 리뷰 배열 n개를 한 번 순회하여 O(n) 시간이 걸리고, 이후 강좌마다 reviewMap[course.id]를 확인하기만 하면 되므로 시간 복잡도 O(1) 이 된다. 

 

 

 

 

'개발 일지' 카테고리의 다른 글

신규 강좌 알림 기능 - Event 기반 아키텍처 리팩토링  (0) 2025.03.03
2. 와이어 프레임 제작  (1) 2025.01.21
1. 프로젝트 계획  (2) 2025.01.20