如何解决React Star Widget - 为什么所有星星都在单击时更新?
我正在尝试创建一个星形小部件。我为每颗星星都有一个状态数组,但是当我单击其中一颗星星时,所有星星都会将自己设置为该状态。我很迷茫,请停顿。我添加了很多调试日志。我设置 newStars[i] = currentStar;
的那一刻,整个 newStars 数组都会更新,但我不明白为什么。
另外,这里是代码笔链接:https://codepen.io/trismi/pen/zYZpvQq?editors=1111
HTML:
<div id="root">
</div>
CSS(加上代码笔中链接的很棒的字体样式表)
.star {
display: inline-block;
width: 30px;
text-align: center;
color: #ddd;
font-size: 20px;
transform: scale(.8);
transition: transform 50ms ease;
&:hover,&.semi-active {
color: gold;
transform: scale(1);
}
&.selected {
color: orange;
transform: scale(1);
}
}
JAVASCRIPT
function Star(props) {
console.log(props);
console.log(props.index);
let classes = 'star' + (props.selected ? ' selected' : '') + (props.hover ? ' semi-active' : '');
return (
<div className={classes} onClick={props.onClick}>
<i className="fas fa-star"></i>
</div>
);
}
class RatingWidget extends React.Component {
constructor(props){
super(props);
this.state = {
stars: Array(5).fill({
selected: false,hover: false,}),}
}
handleClick(currentStar,index) {
console.log('\n\n\n******CLICK');
console.log("star state on click",currentStar);
console.log("index",index);
let newStars = this.state.stars.slice();
let newStar = newStars[index];
console.log("new star ",newStar);
newStar.selected = !newStar.selected;
newStars[index] = newStar;
console.log("stars",newStars);
this.setState({
stars: newStars
});
}
render() {
let stars = this.state.stars.map((rating,index) => {
return (
<Star
key={index}
index={index}
onClick={() => this.handleClick(rating,index)}
selected={rating.selected}
hover={rating.hover}
/>);
});
return (
<div className="RatingWidget">
Future rating widget
{stars}
</div>
);
}
}
ReactDOM.render(<RatingWidget />,document.getElementById('root'));
解决方法
问题出在这里:
Array(5).fill({
selected: false,hover: false,})
您正在为数组的每个元素填充相同的对象(相同的引用)。
尝试使用:
Array(5).fill(null).map(() => ({
selected: false,}))
或者使用 Array.from():
Array.from({length: 5},() => ({ selected: false,hover: false}))
,
你可以有下面的handleClick函数
I updated let newStar = newStars[index]; to let newStar = {...newStars[index]};
handleClick(currentStar,index) {
console.log('\n\n\n******CLICK');
console.log("star state on click",currentStar);
console.log("index",index);
let newStars = this.state.stars.slice();
let newStar = {...newStars[index]};
console.log("new star ",newStar);
newStar.selected = !newStar.selected;
newStars[index] = newStar;
console.log("stars",newStars);
this.setState({
stars: newStars
});
}
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。