mrpbennett
mrpbennett

Reputation: 1976

Star rating in React for a card component

I am trying to display a star rating based on the rating number in an object. I want to display 5 grey stars and then display the rating number of coloured stars

This is my component

import React, { useState } from 'react';
import './card.scss';
import { AiFillStar } from 'react-icons/ai';

const Card = () => {
    const [rating, setRating] = useState(null);
    const cardData = [
        {
            imgUrl:
                'https://images.unsplash.com/photo-1479502806991-251c94be6b15?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80',
            beds: 3,
            baths: 2,
            title: 'Modern apartment in city center',
            price: 390000,
            formattedPrice: '£3,900.00',
            reviewCount: 69,
            rating: 4,
        },
        {
            imgUrl:
                'https://images.unsplash.com/photo-1445019980597-93fa8acb246c?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1353&q=80',
            beds: 1,
            baths: 2,
            title: 'Desert get away in the sun',
            price: 230000,
            formattedPrice: '£2,300.00',
            reviewCount: 108,
            rating: 3,
        },
        {
            imgUrl:
                'https://images.unsplash.com/photo-1553653924-39b70295f8da?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1350&q=80',
            beds: 2,
            baths: 1,
            title: 'Coastal apartment with communal pool',
            price: 900,
            formattedPrice: '£900.00',
            reviewCount: 2567,
            rating: 5,
        },
    ];

    return (
        <div className='cardContainer'>
            {cardData.map((card) => (
                <div className='card'>
                    <img src={card.imgUrl} />
                    <div className='cardInner'>
                        <div className='cardInfoTop deemphasise'>
                            {card.beds} beds &bull; {card.baths} baths
                        </div>

                        <h4>{card.title}</h4>

                        <div className='cardInfoMiddle'>
                            {card.formattedPrice}{' '}
                            <span className='deemphasise'>/ pcm</span>
                        </div>

                        <div className='cardInfoBottom emphasise'>
                            {[...Array(5)].map((star, i) => {
                                const ratingValue = i + 1;
                                return (
                                    <AiFillStar
                                        color={
                                            ratingValue > rating
                                                ? 'teal'
                                                : 'grey'
                                        }
                                    />
                                );
                            })}{' '}
                            <span className='deemphasise ml-2'>
                                based on {card.reviewCount.toLocaleString()}{' '}
                                reviews
                            </span>
                        </div>
                    </div>
                </div>
            ))}
        </div>
    );
};

export default Card;

Because of the following: color={ratingValue > rating ? 'teal': 'grey'} I am always getting 5 coloured stars. Which is great, but I am struggling to figure out how to reproduce the card.rating figure as the coloured stars

Upvotes: 0

Views: 1001

Answers (1)

Ross Mackay
Ross Mackay

Reputation: 972

A small typo + mixed up colours is why you're getting 5!

rating is undefined as it's card.rating, so the condition always returns teal.

If you want it so show the rating as teal (eg rating of 4 is 4 teal stars and 1 grey) you need to swap them around as well

<AiFillStar color={ratingValue > card.rating ? "grey" : "teal"} />
                                   ^card.             ^ swap grey/teal

Upvotes: 1

Related Questions