유저가 받은 별점의 평균을 마이페이지에서 나타내기 위해 소수점까지 처리 가능한 별점을 구현해보았다. 예를 들어 유저의 별점이 5개 만점에 3.2면 별 세개는 채우고 4번째 별은 0.2만큼 나타내고 싶었다.
const [popularity, setPopularity] = useState(3.2);
const STAR_IDX_ARR = ['1', '2', '3', '4', '5'];
const [ratesResArr, setRatesResArr] = useState([0, 0, 0, 0, 0]);
const calcStarRates = () => {
let tempStarRatesArr = [0, 0, 0, 0, 0];
let starVerScore = (popularity * 70)/5 ;
//하나당 별의 넓이가 14이니까 14*5 = 70을 곱하고
//별 개수(5)로 나눠주었따.
let idx = 0;
while (starVerScore > 14) {
tempStarRatesArr[idx] = 14;
idx += 1;
starVerScore -= 14;
}
tempStarRatesArr[idx] = starVerScore;
return tempStarRatesArr;
};
useEffect(() => {
setRatesResArr(calcStarRates);
}, [])
return (
<StarWrapper>
{STAR_IDX_ARR.map((item, idx) => {
return <div className='star_icon' key={`${idx}`}>
<svg xmlns='http://www.w3.org/2000/svg' width='22' height='20' viewBox='0 0 14 13' fill='#cacaca'>
<clipPath id={`${item}StarClip`}>
<rect width={`${ratesResArr[idx]}`} height='39' />
</clipPath>
<path
id={`${item}Star`}
d='M9,2l2.163,4.279L16,6.969,12.5,10.3l.826,4.7L9,12.779,4.674,15,5.5,10.3,2,6.969l4.837-.69Z'
transform='translate(-2 -2)'
/>
<use clipPath={`url(#${item}StarClip)`} href={`#${item}Star`} fill='#5d5fef'
/>
</svg>
</div>
})
}
<span>{popularity}</span>
</StarWrapper>
)