Building a Dynamic Star Rating Component in React with Tailwind CSS and react-icons
Building a custom rating component is a common requirement for many web applications, from e-commerce reviews to user feedback systems. In this post, we'll walk through creating a clean, reusable star rating component using Tailwind CSS and React icons. The component will handle both displaying ratings and accepting user input for interactive star selection.
Required Dependencies
Before we start coding, you'll need to have Tailwind CSS already set up in your project. Assuming that's in place, we just need one additional dependency for the star icons:
npm install react-iconsThis package provides a massive collection of icons, including the star icons we'll use for our rating component.
Building the Rating Component
Our component will accept two props: stars (the current rating value) and maxStars (the maximum number of stars, defaulting to 5). Here's how we'll use it:
<Rating stars={4} maxStars={5} />Understanding the Logic
The core idea is simple: we need to know which stars should be filled (golden) and which should remain empty (gray). We achieve this by creating two arrays:
- Gold stars: An array filled with
1values, representing filled stars - Gray stars: An array filled with
0values, representing empty stars
const goldStars = [...new Array(stars).fill(1)]
const grayStars = [...new Array(maxStars - stars).fill(0)]
const allStars = [...goldStars, ...grayStars]By subtracting stars from maxStars, we calculate how many gray stars are needed. Then we merge both arrays into one for easier rendering.
Rendering the Stars
Now we map through the combined array and conditionally render either a filled or outline star icon:
{allStars.map((item, index) =>
item === 1 ? (
<AiFillStar className="text-yellow-500" />
) : (
<AiOutlineStar />
)
)}The className applies Tailwind's yellow color to filled stars, while outline stars remain gray by default.
Complete Component
Here's the full component with all pieces assembled:
import React from "react";
import { AiFillStar, AiOutlineStar } from "react-icons/ai";
const Rating = ({ stars, maxStars = 5 }) => {
const goldStars = [...new Array(stars).fill(1)];
const grayStars = [...new Array(maxStars - stars).fill(0)];
const allStars = [...goldStars, ...grayStars];
return (
<div className="flex items-center">
{allStars.map((item, index) =>
item === 1 ? (
<AiFillStar key={index} className="text-yellow-500" />
) : (
<AiOutlineStar key={index} />
)
)}
</div>
);
};
export default Rating;Interactive Star Selection
If you want users to be able to click on stars to set a rating, you can extend the component with state management. Here's an enhanced version that supports interactivity:
import React, { useState } from "react";
import { AiFillStar, AiOutlineStar } from "react-icons/ai";
const Rating = ({ maxStars = 5 }) => {
const [rating, setRating] = useState(0);
const [hover, setHover] = useState(0);
return (
<div className="flex items-center">
{[...Array(maxStars)].map((_, index) => {
const starValue = index + 1;
return (
<button
key={index}
type="button"
className="focus:outline-none"
onClick={() => setRating(starValue)}
onMouseEnter={() => setHover(starValue)}
onMouseLeave={() => setHover(0)}
>
{starValue <= (hover || rating) ? (
<AiFillStar className="text-yellow-500" />
) : (
<AiOutlineStar />
)}
</button>
);
})}
</div>
);
};This version includes:
- Rating state: Tracks the current selected rating
- Hover state: Provides visual feedback when users hover over stars
- Click handling: Updates the rating when a star is clicked
- Visual feedback: Fills stars on hover and click
Key Takeaways
- Reusability: The component accepts
starsandmaxStarsprops, making it adaptable to different rating scales - Conditional styling: Uses array logic and Tailwind classes to differentiate filled and empty stars
- Interactivity: Can be extended with simple state management for click-to-rate functionality
- Lightweight: Only requires
react-iconsas an additional dependency
This rating component gives you a solid foundation that you can further customize with animations, different icon sets, or half-star ratings. The pattern of using arrays with conditional rendering is versatile and can be adapted for other similar UI patterns like progress bars or step indicators.
Comments
Related posts
Persist React State Like a Pro: Building a Reusable useLocalState Hook
React's state resets on page refresh, but by combining localStorage with a custom `useLocalState` hook, you can create persistent state that survives browser reloads and sessions while maintaining the familiar `useState` interface.
Jun 13, 2026 · 3 min read
The Hidden Power of useEffect's Return Function
React's useEffect cleanup function is essential for preventing memory leaks and unexpected behavior by properly disposing of timers, event listeners, and subscriptions when components unmount or dependencies change.
Jun 13, 2026 · 3 min read