React Star Widget - 为啥所有星星都在单击时更新?
Posted
技术标签:
【中文标题】React Star Widget - 为啥所有星星都在单击时更新?【英文标题】:React Star Widget - why do all stars update on single click?React Star Widget - 为什么所有星星都在单击时更新? 【发布时间】:2021-08-18 23:54:27 【问题描述】:我正在尝试创建一个星形小部件。我对每颗星星都有一个状态数组,但是当我单击其中一颗星星时,所有星星都会将自己设置为该状态。我对此很迷茫,请停下来。我添加了很多调试日志。在我设置 newStars[i] = currentStar;
的那一刻,整个 newStars 数组都会更新,但我不明白为什么。
另外,这里是代码笔链接:https://codepen.io/trismi/pen/zYZpvQq?editors=1111
html:
<div id="root">
</div>
CSS(加上 codepen 中链接的很棒的字体样式表)
.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);
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'));
【问题讨论】:
【参考方案1】:问题出在这里:
Array(5).fill(
selected: false,
hover: false,
)
您正在为数组的每个元素填充相同的对象(相同的引用)。
尝试使用:
Array(5).fill(null).map(() => (
selected: false,
hover: false,
))
或者使用 Array.from():
Array.from(length: 5, () => ( selected: false, hover: false))
【讨论】:
非常感谢!这让我发疯了。现在开始处理悬停的东西:D【参考方案2】:你可以有下面的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
);
【讨论】:
以上是关于React Star Widget - 为啥所有星星都在单击时更新?的主要内容,如果未能解决你的问题,请参考以下文章
评级不选择超过 3 星 - React Native Elements - 评级)