원티드 X 코드스테이츠 프리온보딩 프론트엔드 과정 기업과제 9번
담당했던 부분 : 별점 컴포넌트 작성
✨ 주요 기능
고객이 리뷰를 등록 하고 리뷰를 확인할 수 있습니다.
리뷰 등록 페이지 : 제목, 이미지 선택, 평점을 등록할 수 있습니다.
상품 리뷰 리스트 페이지 : 고객들이 구매한 상품에 대한 전체 리뷰를 무한스크롤을 이용해 정렬되어(최신순, 리뷰카운트 순, 랜덤) 확인 할 수 있는 페이지입니다. 그리드뷰와 리스트뷰를 제공합니다.
상품 리뷰 상세 페이지 : 특정 리뷰를 클릭하면 보이는 리뷰 상세 페이지입니다. 댓글달기 기능과 좋아요, 링크공유 기능을 제공합니다.
이번 프로젝트에서는 별점 컴포넌트 작성을 담당하게 되었다.
클릭하면 사용자가 별점을 클릭한만큼 색이 바뀌도록 디자인하였다.
로직은 checkedArr이라는 배열을 선언하고 이를 별점의 수만큼 false로 할당해 놓았다.
setClickState는 별점이 눌리면 false에서 true로 상태값을 바꾸는 함수이다.
클릭된 인덱스만 바꾸는 게 아니라 그 전의 모든 인덱스 값을 true로 바꿔야만 별점처럼 작동한다는 것이 핵심이었다.
const Ratings = ({ setCountRate }) => {
const checkedArr = [false, false, false, false, false]
const [clickState, setClickState] = useState(checkedArr)
const [state, setState] = useState('')
const handleClick = (idx) => {
const arr = checkedArr
for (let i = 0; i < 5; i++) {
arr[i] = i <= idx ? true : false
}
setClickState(arr)
setCountRate(idx + 1)
}
return (
<>
<div
style={{
padding: '15px 75px',
display: 'flex',
}}
>
{checkedArr.map((list, idx) => (
<section key={idx}>
<input
type="checkbox"
style={{ display: 'none' }}
value={state || ''}
onChange={(e) => setState(e.target.value)}
/>
<div>
<FaStar
color={clickState[idx] ? '#fdcb6e' : 'rgba(0,0,0,0.2)'}
size={50}
onClick={() => handleClick(idx)}
style={{
padding: '3px',
stroke: 'gray',
strokeWidth: '5px',
}}
/>
</div>
</section>
))}
</div>
</>
)
}
export default Ratings
SetCountRate는 인덱스 값과 실제로 카운트되는 값이 1이 차이나기 때문에 그를 맞춰주기 위해 +1을 해 주는 상태이다.
const ReviewUpload = () => {
const [countRate, setCountRate] = useState(0)
return (
<>
<label htmlFor="inputFile" className="review-file-label">
+ 이미지 추가
</label>
<input
id="inputFile"
type="file"
className="review-file"
onChange={handleImgChange}
></input>
<h3 className="review-title">별점</h3>
<Ratings setCountRate={setCountRate}></Ratings>
<button className="review-submit">저장하기</button>
</form>
</>
)
}
export default ReviewUpload