내용
- 마우스 오버로 해당 오버 별 순번까지 드래그
- 해당 별 평점 텍스트 나타내기
- 해당 별 클릭시 색깔 유지
- 클릭한 해당 별 인덱스 저장 후 백엔드로 데이터 보냄
결과

코드
import React, { useState } from 'react';
import styled from 'styled-components';
const Score = () => {
const [hovered, setHovered] = useState(null);
const [clicked, setClicked] = useState(null);
const goToFetch = e => {
setClicked(e.target.id);
fetch(`http://10.58.3.24:8000/products/1`, {
method: 'POST',
headers: {
Authorization: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.loTjeBWZ9SeXV-BcIxqOtX37AN30ROvsZl0_udeeRJU',
},
body: JSON.stringify({
rating: e.target.id,
}),
});
};
return (
<ReviewBox>
<ReviewTextBox>
<p>이 책을 평가해주세요!</p>
{[1, 2, 3, 4, 5].map(num => (
<HiddenText key={num} show={hovered === num}>
{textList[num - 1]}
</HiddenText>
))}
</ReviewTextBox>
<StarContainer>
{[1, 2, 3, 4, 5].map(el => (
<i
className={`fas fa-star ${
(clicked >= el) | (hovered >= el) && 'yellowStar'
}`}
key={el}
onMouseEnter={() => setHovered(el)}
onMouseLeave={() => setHovered(null)}
onClick={() => setClicked(el)}
/>
))}
</StarContainer>
</ReviewBox>
);
};
export default Score;
const textList = [
'별로에요',
'그저 그래요',
'보통이에요',
'좋아요',
'최고예요',
];
const ReviewBox = styled.div`
padding: 30px;
color: #999;
font-size: 20px;
i {
margin: 20px 10px 20px 0;
opacity: 0.1;
cursor: pointer;
font-size: 50px;
}
.yellowStar {
color: orange;
opacity: 1;
}
`;
const ReviewTextBox = styled.div`
position: relative;
text-align: center;
padding-bottom: 50px;
`;
const StarContainer = styled.div`
text-align: center;
border: none;
background-color: white;
`;
const HiddenText = styled.p`
position: absolute;
top: 50px;
left: 50%;
width: 130px;
height: 30px;
padding-top: 7px;
transform: translate(-50%, -50%);
color: white;
background-color: #1f8ce6;
border-radius: 4px;
font-size: 16px;
${({ show }) => (show ? `display:block` : `display: none`)}
`;
마우스 오버시 해당 별 순번까지 드래그, 해당 별 클릭시 색깔 유지
const [hovered, setHovered] = useState(null);
const [clicked, setClicked] = useState(null);
<StarContainer>
{[1, 2, 3, 4, 5].map(el => (
<i
className={`fas fa-star ${
(clicked >= el) | (hovered >= el) && 'yellowStar'
}`}
key={el}
id={el}
onMouseEnter={() => setHovered(el)}
onMouseLeave={() => setHovered(null)}
onClick={goToFetch}
/>
))}
</StarContainer>
const ReviewBox = styled.div`
padding: 30px;
color: #999;
font-size: 20px;
i {
margin: 20px 10px 20px 0;
opacity: 0.1;
cursor: pointer;
font-size: 50px;
}
.yellowStar {
color: orange;
opacity: 1;
}
`;
해당 별 평점 텍스트 나타내기
const textList = [
'별로에요',
'그저 그래요',
'보통이에요',
'좋아요',
'최고예요',
];
const [hovered, setHovered] = useState(null);
<ReviewTextBox>
<p>이 책을 평가해주세요!</p>
{[1, 2, 3, 4, 5].map(num => (
<HiddenText key={num} show={hovered === num}>
{textList[num - 1]}
</HiddenText>
))}
</ReviewTextBox>
<StarContainer>
const HiddenText = styled.p`
position: absolute;
top: 50px;
left: 50%;
width: 130px;
height: 30px;
padding-top: 7px;
transform: translate(-50%, -50%);
color: white;
background-color: #1f8ce6;
border-radius: 4px;
font-size: 16px;
${({ show }) => (show ? `display:block` : `display: none`)}
`;
클릭한 해당 별 인덱스 저장 후 백엔드로 데이터 보냄
<StarContainer>
{[1, 2, 3, 4, 5].map(el => (
<i
className={`fas fa-star ${
(clicked >= el) | (hovered >= el) && 'yellowStar'
}`}
key={el}
id={el}
onMouseEnter={() => setHovered(el)}
onMouseLeave={() => setHovered(null)}
onClick={goToFetch}
/>
))}
</StarContainer>
const goToFetch = e => {
console.log('eti', e.target.id);
setClicked(e.target.id);
fetch(`http://10.58.3.24:8000/products/1`, {
method: 'POST',
headers: {
Authorization: 'eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJ1c2VyX2lkIjoxfQ.loTjeBWZ9SeXV-BcIxqOtX37AN30ROvsZl0_udeeRJU',
},
body: JSON.stringify({
rating: e.target.id,
console.log('clicked->', { clicked });
}),
});
};