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 |