本文同时发布于掘金,地址:https://juejin.im/post/6844903858523783176
本文译自:30-seconds-of-react 。React 30 秒速学: 精选有用的 React 片段,30-seconds-of-react 的中文版本,已全部完成翻译、上线,地址:30-seconds-of-react-zh_CN-umi 。
星级评分组件
- 定义一个名为“Star”的组件,它将根据父组件的状态为每个星形呈现适当的外观。
- 在
StarRating
组件中,使用React.useState()
钩子来定义rating
和selection
状态变量,初始值为props.rating
(如果无效或未传入,则为 0 )和 0 。 - 创建一个方法
hoverOver
,根据传入的event
更新selected
和rating
。 - 创建一个
<div>
来包装<Star>
组件,这些组件是使用Array.prototype.map
在5个元素的数组上创建的,使用Array.from
创建,并处理onMouseLeave
将selection
设置为0
的事件,onClick
事件设置rating
和onMouseOver
事件,分别将selection
设置为event.target
的star-id
属性。 - 最后,将适当的值传递给每个
<Star>
组件(starId
和marked
)。
星星组件:
function Star({ marked, starId }) {
return (
<span star-id={starId} style={{ color: "#ff9933" }} role="button">
{/* 空星,实星 */}
{marked ? "\u2605" : "\u2606"}
</span>
);
}
星级评分:
function StarRating(props) {
// 分数显示
const [rating, setRating] = React.useState(
typeof props.rating == "number" ? props.rating : 0
);
// 鼠标移入效果
const [selection, setSelection] = React.useState(0);
const hoverOver = event => {
let val = 0;
if (event && event.target && event.target.getAttribute("star-id"))
val = event.target.getAttribute("star-id");
setSelection(val);
};
return (
<div
// 鼠标移入效果
onMouseOut={() => hoverOver(null)}
// 点击选中分数
onClick={event =>
setRating(event.target.getAttribute("star-id") || rating)
}
onMouseOver={hoverOver}
>
{/* 创建5个组件 */}
{Array.from({ length: 5 }, (v, i) => (
<Star
starId={i + 1}
key={`star_${i + 1} `}
marked={selection ? selection >= i + 1 : rating >= i + 1}
/>
))}
</div>
);
}
例子
export default function() {
return <div>
<StarRating />
<StarRating rating={2} />
</div>;
}