Skip to content

feat: 06-StarRating 구현 (이경하)#26

Open
k0nghaa wants to merge 3 commits into
mainfrom
feat/06-StarRating-kyeongha
Open

feat: 06-StarRating 구현 (이경하)#26
k0nghaa wants to merge 3 commits into
mainfrom
feat/06-StarRating-kyeongha

Conversation

@k0nghaa

@k0nghaa k0nghaa commented Jun 21, 2026

Copy link
Copy Markdown
Member

📝 과제 요약

  • 과제명: Star Rating
  • 소요 시간: 3시간

💡 설계 및 고민한 부분

AI 없이 스스로 설계하며 가장 신경 쓴 핵심 로직이나 아키텍처(컴포넌트 구조, 상태 관리 등), 혹은 사용자 경험(UX) 개선 사항을 적어주세요.

  • 별점을 0점부터 시작하게 하여 첫번째 별로 클릭 시 빈 별이 될 수 있게 했습니다.

📖 학습한 내용 및 어려웠던 점 (선택)

문제를 풀며 새롭게 알게 된 개념이나, 구현 중 막혔던 부분이 있다면 공유해 주세요.

머릿속으로는 쉽게 그려졌는데 막상 코드로 구현하려니 어렵네요 🥲
잘못 생각했던 부분이나 막힌 부분을 공유해보려 합니다.

1. 배열이 아닌 컴포넌트를 전달받은 maxStar 값에 맞춰 렌더링해야한다.

  • Array.from({ length: maxStar }) 을 사용해 maxStar에 맞는 빈 배열을 만들어 map 메서드를 사용할 수 있었습니다.

2. 토글 구현처럼 (setIsFilledStar((prev) => !prev);) 값을 반전하는 방식을 사용한다.

  • 해당 방식을 사용하면 이전 인덱스와 비교해서 true/false를 일일이 바꾸는 방식으로 구현해야했습니다. 이 방식은 React 보다 바닐라 자바스크립트 스타일에 가까웠습니다.
  • 이전 인덱스보다 작으면 false로 바꾸는 등 복잡한 분기 처리 없이 현재 인덱스와 클릭된 상태 값을 비교하여 렌더링했습니다. (index < clickedRating)

3. 호버(isHovered)와 클릭(isFilled) 값을 Star에 따로 넘겨준다.

  • 처음엔 호버와 클릭을 따로 넘겨줬는데, 그렇게 하니 우선순위(호버했을 땐 클릭된 값은 잠시 무시하고 호버된 값을 기준으로 별을 채운다) 를 맞추기 어려웠습니다. (예: 클릭한 별 수가 3개이면 2개 이하를 호버했을 때 계속해서 3개의 별이 채워져있음)
  • 마우스가 올라가 있는 상태(isHoveredStar !== null)인지를 기준으로 호버 상태와 클릭 상태를 정하게 되고 해당 상태와 index를 비교해 <Star />isFilled로 전달합니다.
  • Star 컴포넌트는 호버, 클릭 상관없이 별이 채워져있는지 비워져있는지만 알고 그리게 됩니다.

❓ 질문 사항 (선택)

라이브 리뷰 때 팀원들과 함께 토론하고 싶거나 의견이 궁금한 부분이 있다면 남겨주세요.

The widget accepts three parameters: the maximum number of stars, the number of currently filled stars, and a callback fired with the new value whenever the rating changes.
위젯은 세 가지 매개변수를 수용합니다: 최대 별의 수, 현재 채워진 별의 수, 그리고 평점이 바뀔 때마다 새 값으로 호출되는 콜백입니다.

  • 세가지 매개변수를 수용한다는 문제의 요구사항 중 현재 채워진 별의 수그리고 평점이 바뀔 때마다 새 값으로 호출되는 콜백은 사용하지 못했는데, 혹시 다들 사용하셨는지 궁금합니다 ..!

📸 스크린샷 (선택)

UI 관련 과제인 경우 결과 화면 캡처나 GIF를 첨부해 주세요.

화면 기록 2026-06-22 오전 12 39 10
  • 호버임을 나타낼 수 있는 스타일을 추후에 추가해야겠네요 ••

@k0nghaa k0nghaa self-assigned this Jun 21, 2026

@hyun-june hyun-june left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

고생하셨습니다!

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

isFilled 값에 따라 SVG 전체를 조건부 렌더링하기보다는, className이나 fill 값만 조건부로 변경하면 코드 중복을 줄일 수 있을 것 같습니다.

현재는 채워진 별과 빈 별의 SVG 구조가 거의 동일해서, 공통 SVG는 한 번만 작성하고 달라지는 속성만 분기해도 좋을 것 같습니다!

Comment on lines +36 to +47
<>
{starArray.map((_, index) => (
<button
key={index}
onClick={() => handleFilledStar(index)}
onMouseEnter={() => handleMouseEnter(index)}
onMouseLeave={handleMouseLeave}
>
<Star isFilled={index < activeRating} />
</button>
))}
</>

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

현재는 빈태그로 별 목록만 반환하고 있어, App.tsx에서 사용할 때마다 레이아웃을 위한 wrapper를 따로 작성해야 할 수도 있을 것 같습니다.
StarRating 자체가 하나의 UI 단위라면 내부에서 divul 같은 컨테이너를 제공하는 방식도 고려해보시면 좋을 것 같습니다.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants