Create a custom React star rating component
Tags: react, javascript, tutorial
Published: 2020-12-04 03:06:25

In this tutorial we’ll be building a custom React star rating component. This type of component allows users to give something a rating between 1 and 5 stars with a single mouse click.

Here’s how the completed component will look & function:

![Alt Text](https://dev-to-uploads.s3.amazonaws.com/i/meeudjpxbvmyyo1abytj.gif)

Let’s get started by setting up an application using [Create React App](https://www.michaelburrows.xyz/create-react-app/):

`npx creat-react-app star-rating`

Then in the `/src` directory create a file for the component named `StarRating.js`. We’ll start with a bare bones component to test the setup then build out the full functionality:

```javascript
import React, { useState } from "react";

const StarRating = () => {  
  return (<p>Hello World</p>);
};

export default StarRating;
```

Next replace the contents of the `App.js` file to load in the component:

```javascript
import StarRating from "./StarRating";
import "./App.css";

const App = () => {
  return (
    <div className="App">
      <StarRating />
    </div>
  );
};

export default App;
```

Run the `npm start` command and test that the component is being loaded.

Now back to the `StarRating.js` file, first thing we need to do is have the component output 5 stars which we do by mapping over an array:

```javascript
const StarRating = () => {
  return (
    <div className="star-rating">
      {[...Array(5)].map((star) => {        
        return (         
          <span className="star">&#9733;</span>        
        );
      })}
    </div>
  );
};
```

`&#9733;` is the HTML entity code for a star icon but you could also use an icon library like Font Awesome here if you wanted. Next we need to add the functionality that sets the star rating when clicked. For this we’ll wrap the stars in a `<button>` and with a `onClick()` event:

```javascript
const StarRating = () => {
  const [rating, setRating] = useState(0);
  return (
    <div className="star-rating">
      {[...Array(5)].map((star, index) => {
        index += 1;
        return (
          <button
            type="button"
            key={index}
            className={index <= rating ? "on" : "off"}
            onClick={() => setRating(index)}
          >
            <span className="star">&#9733;</span>
          </button>
        );
      })}
    </div>
  );
};
```

We’re using the [State hook](https://reactjs.org/docs/hooks-state.html) to store the value (index) of the star clicked. Depending on the rating selected a class of either “on” or “off” is added, this will allow us to style the icons to give a visual representation of the rating selected.

And here is the CSS which we’ll add to the App.css file:

```css
button {
  background-color: transparent;
  border: none;
  outline: none;
  cursor: pointer;
}
.on {
  color: #000;
}
.off {
  color: #ccc;
}
```

With the CSS setup we have a functioning component that will show the star rating selected on click. For some added interactivity we’ll also implement a hover effect that indicates the rating that will be selected on click:

```javascript
const StarRating = () => {
  const [rating, setRating] = useState(0);
  const [hover, setHover] = useState(0);
  return (
    <div className="star-rating">
      {[...Array(5)].map((star, index) => {
        index += 1;
        return (
          <button
            type="button"
            key={index}
            className={index <= (hover || rating) ? "on" : "off"}
            onClick={() => setRating(index)}
            onMouseEnter={() => setHover(index)}
            onMouseLeave={() => setHover(rating)}
          >
            <span className="star">&#9733;</span>
          </button>
        );
      })}
    </div>
  );
};
```

There you have it, a custom star rating component without the need for any additional dependencies or frameworks. As usual the source code for this project can be found on [GitHub](https://github.com/michael-burrows-github/blog/tree/master/2020/049%20-%20Create%20a%20custom%20React%20star%20rating%20component). Thanks for reading :)