이 코드는 백엔드와의 데이터 통신을 고려하지 않고 짜여진 코드입니다.
백엔드와의 데이터 통신을 고려하여 짜여진 코드는 추후 별점 그래프와 함께 추가될 예정입니다.
즉, 이 코드는 순수 별점기능만을 보여줍니다.
기능은 총 3가지가 있습니다.
1. 별을 클릭하면 별점이 매겨지는 기능(마우스 클릭)
2.같은 별점을 다시 클릭하면 취소하기가 되는 기능 ex) 별점 3점을 누른 후 다시 3점을 누르면 별이 모두 회색으로 변합니다.
3.마우스 Hover기능 (마우스 클릭으로 별점 4점을 줬어도 마우스 Hover시 1점~5점 자유롭게 이동가능)
<StarRating.js>
import React, { Component } from 'react';
import EachStar from './EachStar/EachStar';
import './StarRating.scss';
export default class StarRating extends Component {
constructor() {
super();
this.state = {
rateValue: [false, false, false, false, false],
hoverRateValue: [false, false, false, false, false],
isHover: false,
};
}
handleStarClick = clickedIndex => {
const prevRateValue = [...this.state.rateValue];
const isClickedStarActive = prevRateValue[clickedIndex];
const isNextStarActive = prevRateValue[clickedIndex + 1];
if (isClickedStarActive && isNextStarActive) {
prevRateValue.fill(false, clickedIndex + 1);
this.setState({
isHover: false,
hoverRateValue: [false, false, false, false, false],
rateValue: prevRateValue,
});
return;
}
if (isClickedStarActive) {
prevRateValue.fill(false, 0, clickedIndex + 1);
this.setState({
isHover: false,
hoverRateValue: [false, false, false, false, false],
rateValue: prevRateValue,
});
return;
}
if (!isClickedStarActive) {
prevRateValue.fill(true, 0, clickedIndex + 1);
this.setState({
isHover: false,
hoverRateValue: [false, false, false, false, false],
rateValue: prevRateValue,
});
return;
}
};
handleStarMousehover = hoveredIndex => {
const prevRateValue = [...this.state.hoverRateValue];
const isClickedStarActive = prevRateValue[hoveredIndex];
const isNextStarActive = prevRateValue[hoveredIndex + 1];
if (isClickedStarActive && isNextStarActive) {
prevRateValue.fill(false, hoveredIndex + 1);
this.setState({
isHover: true,
hoverRateValue: prevRateValue,
});
return;
}
if (isClickedStarActive) {
prevRateValue.fill(false, 0, hoveredIndex + 1);
this.setState({
isHover: true,
hoverRateValue: prevRateValue,
});
return;
}
if (!isClickedStarActive) {
prevRateValue.fill(true, 0, hoveredIndex + 1);
this.setState({
isHover: true,
hoverRateValue: prevRateValue,
});
return;
}
};
handleStarMouseout = () => {
this.setState({
isHover: false,
hoverRateValue: [false, false, false, false, false],
});
};
checkIsActive = star => {
if (this.state.isHover) {
if (this.state.hoverRateValue[star]) {
return 'activeStar';
}
return 'inactiveStar';
}
if (this.state.rateValue[star]) {
return 'activeStar';
}
return 'inactiveStar';
};
render() {
const starArray = [0, 1, 2, 3, 4];
return (
<>
<div className="starList">
{starArray.map((star, index) => {
return (
<button
key={index}
onClick={() => this.handleStarClick(star)}
onMouseEnter={() => this.handleStarMousehover(star)}
onMouseLeave={() => this.handleStarMouseout()}
>
<EachStar size={this.props.size} name={this.checkIsActive(star)} />
</button>
);
})}
</div>
</>
);
}
}
<StarRating.scss>
.starList {
display: flex;
button {
fill: grey;
}
}
<EachStar.js>
import React, { Component } from 'react';
import './EachStar.scss';
export default class EachStar extends Component {
render() {
return (
<div className="eachStar">
<svg
className={this.props.name}
height={this.props.size}
viewBox="0 -10 511.98685 511"
width={this.props.size}
xmlns="http://www.w3.org/2000/svg"
>
<path d="m510.652344 185.902344c-3.351563-10.367188-12.546875-17.730469-23.425782-18.710938l-147.773437-13.417968-58.433594-136.769532c-4.308593-10.023437-14.121093-16.511718-25.023437-16.511718s-20.714844 6.488281-25.023438 16.535156l-58.433594 136.746094-147.796874 13.417968c-10.859376 1.003906-20.03125 8.34375-23.402344 18.710938-3.371094 10.367187-.257813 21.738281 7.957031 28.90625l111.699219 97.960937-32.9375 145.089844c-2.410156 10.667969 1.730468 21.695313 10.582031 28.09375 4.757813 3.4375 10.324219 5.1875 15.9375 5.1875 4.839844 0 9.640625-1.304687 13.949219-3.882813l127.46875-76.183593 127.421875 76.183593c9.324219 5.609376 21.078125 5.097657 29.910156-1.304687 8.855469-6.417969 12.992187-17.449219 10.582031-28.09375l-32.9375-145.089844 111.699219-97.941406c8.214844-7.1875 11.351563-18.539063 7.980469-28.925781zm0 0" />
</svg>
</div>
);
}
}
<EachStar.scss>
.eachStar {
.inactiveStar {
fill: #eeeeee;
}
.activeStar {
fill: #ffc107;
}
}
'React > Today I learned' 카테고리의 다른 글
[React] useEffect hook (0) | 2021.12.14 |
---|---|
[React] hook, props, state, event + batch (0) | 2021.12.10 |
fetch함수를 이용한 로그인&회원가입 (0) | 2021.07.02 |
state,props,event (0) | 2021.07.01 |
Sass (0) | 2021.06.30 |