재사용 가능한 StarRating component

Juyeon Lee·2023년 7월 23일
0

REACT 리액트

목록 보기
61/65

StarRating 컴포넌트를 만들어서 화면에 별점을 나타낼 수 있도록 만드려고 한다.

StarRating 컴포넌트 구현

아래의 코드를 보면 maxRating이라는 prop으로 별점 최대 개수를 정할 수 있도록 했다.
{maxRating = 5} 로 default value를 5로 정해주었다. 이렇게 default value를 정해주면 maxRating 값이 지정되지 않았을 경우에 기본값으로 5를 사용한다.

export default function StarRating({maxRating = 5}) {
  return (
    <div style={containerStyle}>
      <div style={starContainerStyle}>
        {Array.from({ length: maxRating}, (_, i) => (
          <span>S{i + 1}</span>
        ))}
      </div>
      <p style={textStyle}>10</p>
    </div>
  );
}

먼저

        {Array.from({ length: maxRating}, (_, i) => (
          <span>S{i + 1}</span>
        ))}

이 코드는 예전에도 벨로그에 정리했었는데 length의 수만큼 array를 생성해 주는것이다. 그리고 i+1 값을 갖는 span 요소들로 이루어진 배열 또한 반환한다.

StarRating 컴포넌트 사용

    <StarRating maxRating={5} />
    <StarRating maxRating={10} />
    <StarRating />

이런식으로 resuable하게 사용할 수 있다.

  • StarRating maxRating={5} : 5개의 별점을 사용하는 StarRating 컴포넌트
  • StarRating maxRating={10} : 10개의 별점을 사용하는 StarRating 컴포넌트
  • StarRating : 기본값(5개의 별점)을 사용하는 StarRating 컴포넌트

결과값은 이렇게 나온다.

별 아이콘을 사용한 별점 표시와 이벤트 구현

이제 S가 아닌 별모양 아이콘으로 구현해보자

export default function StarRating({ maxRating = 5 }) {
  const [rating, setRating] = useState(0);

  return (
    <div style={containerStyle}>
      <div style={starContainerStyle}>
        {Array.from({ length: maxRating }, (_, i) => (
          <Star
            key={i}
            onRate={() => setRating(i + 1)}
            full={rating >= i + 1}
          />
        ))}
      </div>
      <p style={textStyle}>{rating || ""}</p>
    </div>
  );
}

이 코드를 보면

 onRate={() => setRating(i + 1)}
 .
 .
 .
 <p style={textStyle}>{rating || ""}</p>

별을 눌렀을 때 옆에 숫자가 나오도록 만들어준것을 알 수 있다. rating이 없으면 아무것도 나오지 않게 ""로 설정해주었다.

full={rating >= i + 1}

이 코드는 클릭한 만큼 꽉찬 별이 나오게 해주는 코드다.
예를들어 rating이 3이면
맨처음 별의 index인 0 + 1 보다 크니까 첫번째 별은 꽉차고
두번째 별의 index인 1 + 1 보다 크니까 두번째 별도 꽉차고
세번째 별의 index인 2 + 1 와 같으니까 세번째 별도 꽉찬다.
네번째 별부터는 index인 3 + 1 보다 rating이 크지 않다. 그래서
별이 꽉 차지 않는다. 이 full은 이 함수에 props로 들어간다.

function Star({ onRate, full }) {
  return (
    <span role="button" style={starStyle} onClick={onRate}>
      {full ? (
        꽉찬 별 아이콘 코드
      ) : (
        비어있는 별 아이콘 코드
      )}
    </span>
  );
}

이 코드를 보면 onRate와 full 둘다 prop으로 받아서 사용했다. full 이 true면 꽉찬 별 아이콘이 나오도록 아니면 비어있는 별 아이콘이 나오도록 conditioning 해주었다.

1개의 댓글

comment-user-thumbnail
2023년 7월 23일

공감하며 읽었습니다. 좋은 글 감사드립니다.

답글 달기