Chances are if you've ever used a thing called the internet, you have come across a widget that allows you to rate a product by a specific star count. These widgets are rampant across e-commerce websites, and can make or break a product. My goal today is to show you how incredibly easy it is to build one with React.
Let's get started by creating a basic React component.
import { useState } from 'react';
const Stars = () => {
const [numStars, setNumStars] = useState(0);
return (
<div className="stars">
</div>
);
};
Nothing crazy going on here. All I'm doing is setting up a piece of state that will track how many stars the user has chosen. By default it is 0. Next, we need to tackle creating the stars.
For the stars, we are going to use this PNG image that contains both an empty star and a filled star.
We will then create five divs, and set the PNG as a background image on each one. Depending on whether
the star is filled or not depends on the numStars
variable, which is how many stars the user clicked on.
In a separate CSS file, let's write out the styling for these stars.
.stars {
display: flex;
}
.star {
background: url('/images/blog/misc/star.png');
no-repeat 0 0;
height: 21px;
width: 21px;
margin: 3px;
cursor: pointer;
}
.star.active {
background: url('/images/blog/misc/star.png');
no-repeat 0 -21px;
}
As you can see, when a star is marked as active
we change the background positioning to show the filled star instead of the default empty star.
Now that we've figured out our CSS, we need to create five stars to display on the page. We can do so by creating an array with a length of five, and mapping over it.
import { useState } from 'react';
const Stars = () => {
const [numStars, setNumStars] = useState(0);
return (
<div className="stars">
{Array.from({ length: 5 }).map((el, index) => (
<div
key={index}
className="star"
/>
))}
</div>
);
};
This now results in five empty stars being displayed on the page. All that we need to do from here is add click functionality, and add a conditional statement that ensures we are properly displaying a filled or unfilled star.
import { useState } from 'react';
const Stars = () => {
const [numStars, setNumStars] = useState(0);
return (
<div className="stars">
{Array.from({ length: 5 }).map((el, index) => (
<div
key={index}
className={index + 1 <= numStars ? 'star active' : 'star'}
onClick={() => setNumStars(index + 1)}
/>
))}
</div>
);
};
That's all that there is to it! If you have any problems understanding any of this this, feel free to shoot me a message, and I'll make sure it's crystal clear.
You can use the star component below!