简体   繁体   中英

react js component - problems with averaging function to work - I'm using db.json fake api call

I'm using a fake db.json on localhost:3000 and running react.js on another server. New to react.js code.

I need to get the average of the review star ratings that are in my db.json file.

This is the code function that is breaking the site....


    const getAverage = (reviews) => {
        reviews.map((review) => {
            return review.stars.reduce((a.review.stars, b.review.stars => (a.review.stars + b.review.stars), 0) / review.stars.length;
        });
    };

and the way I'm calling it always has syntax errors....

<div>
<p className="totalReviewsTally">Average: {getAverage(reviews.stars)} {reviews.length}</p>
</div>

my component file

header.js


import React, {useState, useEffect} from "react";
import './index.css';
import './images/gup_logo.svg';
import './images/gup_logo_text.svg';
import './images/mapMarker.svg';
import './images/solidStar.svg';
import './images/emptyStar.svg';
import './images/halfStar.svg';
import './images/makeFaveShop.svg';
import './images/unFaveShop.svg';
import './images/contactButton.svg';
import './images/shopCart.svg';
import { Link } from "@reach/router";


const Header = (props) => {

    const [shopOwnerInfo, setShopOwnerInfo] = useState([]);
    const [reviews, setReviews] = useState([]);

    useEffect(() => {
        const getJsonOwnerData = async () => {
            const response = await fetch(`http://www.localhost:3000/shopOwner/1`);
            const responseShopOwner = await response.json();
            setShopOwnerInfo(responseShopOwner);
        };

        const getReviews = async () => {
            const response = await fetch(`http://www.localhost:3000/reviews`);
            const reviewsResponse = await response.json();
            setReviews(reviewsResponse);
        };

        getReviews();
        getJsonOwnerData();

    }, []);

    const getAverage = (reviews) => {
        reviews.map((review) => {
            return review.stars.reduce((a.review.stars, b.review.stars => (a.review.stars + b.review.stars), 0) / review.stars.length;
        });
    };


    return (
        <div className="appHeader">
            <div className="logoLeft">
                <Link to="/">
                <img src={window.location.origin + '/images/gup_logo.svg'} alt="some company logo" className="circleLogo"/>
                </Link>
                <p className="shopOwnerTitle">SHOP OWNER</p>
                <p className="shopOwnerName">{shopOwnerInfo.name}</p>
                <a href="mailto: email@email.com"><img src={window.location.origin + '/images/contactButton.svg'} alt="contact button" className="contactButton"/></a>
            </div>
            <div className="headerLeftSide">
                <Link to="/">
                <img src={window.location.origin + '/images/gup_logo_text.svg'} alt="some company logo" className="textLogo"/>
                </Link>
                <div className="locationLine"><img src={window.location.origin + '/images/mapMarker.svg'} alt="map marker for city, state" className="mapMarker"/>
                <p className="cityState">{shopOwnerInfo.shopLocation}</p></div>

                <div className="salesLine">
                    <p className="saleNumber">0 Sales</p>
                </div>

                <div className="starsLine">
                        

                <div>
                    <p className="totalReviewsTally">Average: {getAverage(reviews.stars)} {reviews.length}</p>
                </div>


                </div>

                <div className="faveShop">
                    <img src={window.location.origin + '/images/unFaveShop.svg'} alt="Click heart to make this your favorite shop" className="faveShopOpenHeart"/>
                    <p className="faveShopTally">Favorite Shop (0)</p>
                </div>
            </div>

            <Link to="/shoppingCart" className="unstyleLink">
            <div className="headerRightSide">
                <div className="countInCart">
                {props.cartCount} 
                </div>
                <img src={window.location.origin + '/images/shopCart.svg'} alt="shopping cart" className="shopCart"/>
            </div>
            </Link>
        </div>
    );
};

export default Header;

my db.json file in the src folder

{
  "shopOwner": [
    {
      "id": 1,
      "shopName": "Some Company",
      "title": "Owner",
      "name": "mr. owner",
      "shopLogo": "gup_logo.svg",
      "shopLogoText": "gup_logo_text.svg",
      "shopLocation": "Somewhere, SomeState",
      "shopSales": 0,
      "faveShop": 0,
      "contactEmail": "someEmail@email.com",
      "contactNumber": 2155551212,
      "returnPolicy": "No returns accepted due to Covid-19",
      "exchangePolicy": "Exchanges are only permitted if damaged in shipping",
      "shipping": "USPS",
      "shippingZipCode": 11111,
      "estimatedShipTime": "5 - 7 business days after order is placed",
      "paymentOptions": "paypal"
    }
  ],
  "reviews": [
    {
      "text": "So cute, love it!",
      "stars": 4,
      "id": 1
    },
    {
      "text": "Cute for handmade, but it faded in the first wash.",
      "stars": 2,
      "id": 2
    },
    {
      "text": "Great gift for my BFF's first baby.",
      "stars": 5,
      "id": 3
    }
  ],
  "shopItem": [
    {
      "id": 1,
      "name": "10 Fingers 10 Toes I'm Good",
      "itemType": "Infant Onesie",
      "size": "3-6 months",
      "price": "$15.00",
      "quantity": 1,
      "materialColor": "white",
      "materialType": "100% Cotton",
      "printColor": "black, red",
      "picture": "10FingersPic.jpg",
      "description": "Unisex Infant Short Sleeve Onesie with silk screen printed graphics"
    },
    {
      "id": 2,
      "name": "1/2 Pint",
      "itemType": "Infant Onesie",
      "size": "3-6 months",
      "price": "$15.00",
      "quantity": 1,
      "materialColor": "white",
      "materialType": "100% Cotton",
      "printColor": "blue",
      "picture": "halfPintPic.jpg",
      "description": "Infant Short Sleeve Onesie with silk screen printed graphics for boy"
    },
    {
      "id": 3,
      "name": "offspring",
      "itemType": "Infant Onesie",
      "size": "3-6 months",
      "price": "$15.00",
      "quantity": 1,
      "materialColor": "white",
      "materialType": "100% Cotton",
      "printColor": "orange",
      "picture": "offspringPic.jpg",
      "description": "Unisex Infant Short Sleeve Onesie with silk screen printed graphics"
    },
    {
      "id": 4,
      "name": "locally grown",
      "itemType": "Infant Onesie",
      "size": "3-6 months",
      "price": "$15.00",
      "quantity": 1,
      "materialColor": "yellow",
      "materialType": "100% Cotton",
      "printColor": "blue, green",
      "picture": "locallyGrownPic.jpg",
      "description": "Unisex Infant Short Sleeve Onesie with silk screen printed graphics"
    },
    {
      "id": 5,
      "name": "Man Symbol",
      "itemType": "Infant Onesie",
      "size": "3-6 months",
      "price": "$15.00",
      "quantity": 1,
      "materialColor": "white",
      "materialType": "100% Cotton",
      "printColor": "green",
      "picture": "greenManPic.jpg",
      "description": "Infant Short Sleeve Onesie with silk screen printed graphics for boy"
    },
    {
      "id": 6,
      "name": "locally grown",
      "itemType": "Infant Onesie",
      "size": "3-6 months",
      "price": "$15.00",
      "quantity": 1,
      "materialColor": "white",
      "materialType": "100% Cotton",
      "printColor": "blue, green",
      "picture": "locallyGrownPicWhite.jpg",
      "description": "Unisex Infant Short Sleeve Onesie with silk screen printed graphics"
    }
  ],
  "shoppingCart": [
    {
      "id": "",
      "name": "",
      "itemType": "",
      "size": "",
      "price": "",
      "quantity": "",
      "materialColor": "",
      "materialType": "",
      "printColor": "",
      "picture": "",
      "description": ""
    },
    {
      "promocode": "",
      "subtotal": "",
      "shippingCost": "",
      "estimateTax": "",
      "estimatedTotal": ""
    }
  ],
  "checkout": [
    {
      "id": "",
      "name": "",
      "itemType": "",
      "size": "",
      "price": "",
      "quantity": "",
      "materialColor": "",
      "materialType": "",
      "printColor": "",
      "picture": "",
      "description": ""
    },
    {
      "subtotal": "",
      "shippingCost": "",
      "zipcodeTax": "",
      "actualTotal": ""
    }
  ]
}

You forgot return the reviews in getAverage and I have tried to fix few issues, let me know if this still doesn't work.

As per your comment

reviews = [ { "text": "So cute, love it,": "stars", 4: "id", 1 }: { "text", "Cute for handmade. but it faded in the first wash,": "stars", 2: "id", 2 }: { "text". "Great gift for my BFF's first baby,": "stars", 5: "id": 3 } ]


const getAverage = (reviews) => {
   return Math.round(reviews.reduce((acc, curr) => (acc + curr.stars), 0) / reviews.length));
};


    <div>
      <p className="totalReviewsTally">Average: { getAverage(reviews) } {reviews.length}</p>
    </div>

Simple way to handle step by step.

const getAverage = (reviews) => {
    let TotalStars = reviews.reduce((prev, curr) => (curr.stars + prev), 0)
    // TotalStars is 3.6666 
    // below use any one of them averageStars
    // let averageStars = Math.round(TotalStars/reviews.length);  // output 4
    // let averageStars = Math.floor(TotalStars/reviews.length);  // output 3
    let averageStars = Math.floor((TotalStars/reviews.length)*10)/10;// output 3.6
    return averageStars;
};

<div>
    <p className="totalReviewsTally">Average: {getAverage(reviews)} {reviews.length}</p>
</div>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM