Failed prop type: The prop `value` is marked as required in `Rating`, but its value is `undefined`

Viewed 1851

Failed prop type: The prop value is marked as required in Rating, but its value is undefined I'm new in react try to solve this but I can't. I am new in ReactJS.

enter image description here

productScreen.js

import React, { useState, useEffect } from 'react';
import { Link } from 'react-router-dom';
import { useDispatch, useSelector } from 'react-redux';
import { Row, Col, Image, ListGroup, Card, Button, Form } from 'react-bootstrap';
import Rating from '../components/Rating';
import Loader from '../components/Loader';
import Message from '../components/Message';
import { ListProductDetails } from '../actions/productActions';

const ProductScreen = ({ history, match }) => {
    const [qty, setQty] = useState(1);
    const dispatch = useDispatch();

    const productDetails = useSelector(state => state.productDetails);
    const { loading, error, product } = productDetails

    useEffect(() => {
        dispatch(ListProductDetails(match.params.id));
    }, [dispatch, match])


    const addToCartHanddler = () => {
        history.push(`/cart/${match.params.id}?qty=${qty}`)
    }

    return (
        <>
            <Link className='btn btn-info my-3' to='/'>
                Go Back
            </Link>
            { loading ? (
                <Loader />
            ) : error ? (
                <Message variant='danger'>{error}</Message>
            ) : (
                <Row>
                    <Col md={6}>
                        <Image src={product.image} alt={product.name} fluid />
                    </Col>
                    <Col md={3}>
                        <ListGroup variant='flush'>
                            <ListGroup.Item>
                                <h3>{product.name}</h3>
                            </ListGroup.Item>
                            <ListGroup.Item>
                                <Rating 
                                    value={product.rating} 
                                    text={`${product.numReviews} reviews`} />
                            </ListGroup.Item>
                            <ListGroup.Item>
                                Price: ${product.price}
                            </ListGroup.Item>
                            <ListGroup.Item>
                                Description: ${product.description}
                            </ListGroup.Item>
                        </ListGroup>
                    </Col>
                    <Col md={3}>
                        <Card>
                            <ListGroup variant='flush'>
                                <ListGroup.Item>
                                    <Row>
                                        <Col>  
                                            Price:
                                        </Col>
                                        <Col>  
                                            <strong>${product.price}</strong>
                                        </Col>
                                    </Row>
                                </ListGroup.Item>

                                <ListGroup.Item>
                                    <Row>
                                        <Col>  
                                            Status:
                                        </Col>
                                        <Col>  
                                            {product.countInStock > 0 ? 'In Stock' : 'Out of Stock'}
                                        </Col>
                                    </Row>
                                </ListGroup.Item>

                                {product.countInStock > 0 && (
                                    <ListGroup.Item>
                                        <Row>
                                            <Col>Qty</Col>
                                            <Col>
                                                <Form.Control as='select' value={qty} onChange={(e) => setQty(e.target.value)}>
                                                    {[...Array(product.countInStock).keys()].map((x) => (
                                                        <option key={x+1} value={x+1}>{x+1}</option>
                                                    ))}
                                                </Form.Control>
                                            </Col>
                                        </Row>
                                    </ListGroup.Item>
                                )}

                                <ListGroup.Item>
                                    <Button 
                                        onClick={addToCartHanddler}
                                        className='btn-block' 
                                        type='button' 
                                        disabled={product.countInStock > 0 ? false : true}>
                                        Add to Cart
                                    </Button>
                                </ListGroup.Item>
                            </ListGroup>
                        </Card>
                    </Col>
                </Row>
            )}
        </>
    )
}

export default ProductScreen

Rating.js

import React from 'react';
import PropTypes from 'prop-types';

const Rating = ({ value, text, color }) => {
    return (
        <div className='rating'>
            <span>
                <i style={{color}}
                    className={
                    value >= 1 
                    ? 'fas fa-star' 
                    : value >= 0.5 
                    ? 'fas fa-star-half-alt' 
                    : 'far fa-star'}></i>
            </span>
            <span>
                <i style={{color}}
                    className={
                    value >= 2 
                    ? 'fas fa-star' 
                    : value >= 1.5 
                    ? 'fas fa-star-half-alt' 
                    : 'far fa-star'}></i>
            </span>
            <span>
                <i style={{color}}
                    className={
                    value >= 3 
                    ? 'fas fa-star' 
                    : value >= 2.5 
                    ? 'fas fa-star-half-alt' 
                    : 'far fa-star'}></i>
            </span>
            <span>
                <i style={{color}}
                    className={
                    value >= 4 
                    ? 'fas fa-star' 
                    : value >= 3.5 
                    ? 'fas fa-star-half-alt' 
                    : 'far fa-star'}></i>
            </span>
            <span>
                <i style={{color}}
                    className={
                    value >= 5 
                    ? 'fas fa-star' 
                    : value >= 4.5 
                    ? 'fas fa-star-half-alt' 
                    : 'far fa-star'}></i>
            </span>
            <span>{text && text}</span>
        </div>
    )
}

Rating.defaultProps = {
    color: '#f8e825'
}

Rating.propTypes = {
    value: PropTypes.number.isRequired,
    text: PropTypes.string.isRequired,
    color: PropTypes.string,
}

export default Rating;
2 Answers

You can define rating as one of defaultProps like color.

Rating.defaultProps = {
    color: '#f8e825',
    rating: 0,
}

you can delete below code

...................

Rating.propTypes =

{ value: PropTypes.number.isRequired,

text: PropTypes.string.isRequired,

color: PropTypes.string,

}

Related