[React] 별점 리뷰 기능 구현

임홍원·2024년 2월 1일
post-thumbnail

프로젝트 진행중 별점과 리뷰를 남기는 기능이 필요했고, 이를 구현한것을 기억하기 위해 이 글을 작성한다.

필자는 react-hook-form을 같이 사용하여 유효성 검사까지 추가하였다.

코드

const arrayIndex = [5, 4, 3, 2, 1];
const [rate, setRate] = useState<number>(1);
<fieldset className={styles['stars-wrapper']}>
                {arrayIndex.map((index) => (
                  <React.Fragment key={index}>
                    <input
                      type='radio'
                      id={`${index}`}
                      value={arrayIndex[index]}
                      {...register('rating', { required: true })}
                    ></input>
                    <label
                      htmlFor={`${index}`}
                      className={styles['stars']}
                      onClick={() => setRatingIndex(index)}
                    >
                      ⭐️
                    </label>
                  </React.Fragment>
                ))}
              </fieldset>

fieldset으로 input을 그룹화를 시켜준다.
5개의 별이 필요하므로 배열을 선언후 map을 실행시킨다.
배열의 값을 5부터 둔 이유는 뒤에서 설명할 것이다.

.stars-container {
  display: flex;
  align-items: center;
  gap:8px;
}

.stars-container > fieldset {
  display: inline-block;
  gap: 8px;
  direction: rtl;
}

.stars {
  font-size: 40px;
  color: transparent;
  text-shadow: 0 0 0 #f0f0f0;
  cursor: pointer;
}

.stars:hover{
  text-shadow: 0 0 0 #FBB900; /* 마우스 호버 */
}

.stars:hover ~ label{
  text-shadow: 0 0 0 #FBB900; /* 마우스 호버 뒤에오는 이모지들 */
}

.stars-wrapper input[type=radio]{
  display: none;
}

.stars-wrapper input[type=radio]:checked ~ label{
  text-shadow: 0 0 0 #FBB900;
}

label로 지정한 .stars에 color: transparent 로 주고 text-shadow를 통해 새로운 색을 부여한다.

별점의 경우 5점별에 마우스를 올리면 뒤에 있는 별들이 같이 hover 되어야 한다.

.stars:hover ~ label{
  text-shadow: 0 0 0 #FBB900; /* 마우스 호버 뒤에오는 이모지들 */
}

1,2,3,4,5번 중에 3번을 호버 한다고 하면, 1번과 2번의 색상이 같이 채워져야한다.

일반 형제 결합자는 A ~ B{} 라고 하면, A 뒤에 위치하는 요소들만 적용된다.

하지만 HTML 상의 요소의 위치는 1번과 2번이 3번의 앞에 존재한다.
따라서 3번 ~ 1번 {} 이 가능할 수 없다.

direction: rtl

direction: rtl을 쓰지 않으면 원래의 방향은 ltr이므로 오른쪽 별부터 하나씩 채워지게 된다.
direction을 통해 방향을 바꾸어준다. rtl을 사용하면 하위 요소들이 오른쪽부터 채워지게 된다.

여기서 배열의 점수를 5,4,3,2,1 로 설정한 이유가 나온다.
ltr로 설정했다면 5 4 3 2 1 이 되어 오른쪽 별 부터 채워지고 이것을 뒤집어 1 2 3 4 5 로 만든다.
원래의 요소가 5 4 3 2 1 이었으므로 별을 클릭했을때 state를 5부터 시작해주었다.

profile
Frontend Developer

0개의 댓글