Project Overview
The goal of this project was to build a reusable star rating component that can:
- Display a customizable number of stars.
- Highlight stars based on the user's rating.
- Change the highlighted stars on hover to provide visual feedback.
- Persist the user's rating after selection.
Technicalities Involved
State Management: The component manages two pieces of state: rating (the user's selected rating) and hover (the star being hovered over).
Dynamic Rendering: The stars are dynamically rendered based on the noOfStars prop, allowing flexibility in the number of stars displayed.
Conditional Styling: The component applies different styles to the stars based on whether they are active (rated or hovered) or inactive.
Code Breakdown
Let's break down the code step by step:
- Import Statements
javascript
import { useState } from "react";
import { FaStar } from "react-icons/fa";
import './styles.css';
useState: React’s useState hook is used to manage the component's state.
FaStar: The star icons are imported from the react-icons library, specifically from Font Awesome's set of icons.
styles.css: A separate CSS file is imported to style the star rating component.
- Component Definition
javascript
export default function StarRating({ noOfStars = 5 }) {
const [rating, setRating] = useState(0);
const [hover, setHover] = useState(0);
StarRating: This is the main component function that renders the star rating UI.
noOfStars: A prop with a default value of 5. It determines the number of stars in the component.
rating: A state variable that stores the user’s current rating.
setRating: A function to update the rating state.
hover: A state variable that tracks the star index the user is currently hovering over.
setHover: A function to update the hover state.
- Event Handlers
javascript
function handleClick(getCurrentIndex) {
setRating(getCurrentIndex);
}
function handleMouseEnter(getCurrentIndex) {
setHover(getCurrentIndex);
}
function handleMouseLeave() {
setHover(rating);
}
handleClick: Updates the rating state to the index of the star that the user clicks.
handleMouseEnter: Updates the hover state to the index of the star the user hovers over, providing real-time feedback.
handleMouseLeave: Resets the hover state to match the current rating when the user stops hovering, ensuring that the stars reflect the user's last selection.
- Rendering the Stars
javascript
return (
<div className="star-rating">
{[...Array(noOfStars)].map((_, index) => {
index += 1;
return (
<FaStar
key={index}
className={index <= (hover || rating) ? "active" : "inactive"}
onClick={() => handleClick(index)}
onMouseMove={() => handleMouseEnter(index)}
onMouseLeave={() => handleMouseLeave()}
size={40}
/>
);
})}
</div>
);
}
Star Rendering: The stars are rendered dynamically using Array(noOfStars).map(). This creates an array with noOfStars elements and maps over it to render the correct number of FaStar components.
index += 1: The index is incremented by 1 to start from 1 instead of 0, aligning with a more intuitive star rating system (1-5 rather than 0-4).
FaStar Component:
key: A unique key is assigned to each star based on its index.
className: The star’s class is determined by whether it is "active" or "inactive". A star is "active" if its index is less than or equal to the hover or rating state, otherwise, it is "inactive".
onClick: Calls handleClick with the star’s index, updating the rating.
onMouseMove: Calls handleMouseEnter with the star’s index, updating the hover state.
onMouseLeave: Calls handleMouseLeave to reset the hover state to the current rating.
size={40}: Sets the size of the star icons to 40 pixels.
Project Summary
State Management: useState is used effectively to manage the current rating and hover states.
Event Handling: User interactions are handled through event listeners for click and hover actions, providing real-time visual feedback.
Dynamic Rendering: The number of stars rendered is controlled via a prop, making the component flexible and reusable.
See project on GitHub