shahriyar.dev
Back to blog
Tailwind-CSSReact-IconsStar-RatingUI-ComponentReact

Building a Dynamic Star Rating Component in React with Tailwind CSS and react-icons

·4 min read

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:

bash
npm install react-icons

This 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:

jsx
<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 1 values, representing filled stars
  • Gray stars: An array filled with 0 values, representing empty stars
jsx
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:

jsx
{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:

jsx
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:

jsx
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 stars and maxStars props, 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-icons as 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