How to get the output when Onchange event occurs in react js?

Hi Experts,

I have been trying to get the output when the user clicks on the Rating component. I can see that the value is been displayed on the console.log but when I try to add my API value, I can not see that change on the screen nor the fill color changing. It says that amovie is not defined.

If any advice on this how and why is it not working would be great. Here I’m using Material UI components.

Please find the code below:

const [ratingValue, setRatingValue] = useState(movie.vote_average);

<Rating 
                                className = {classes.typography2} 
                                name = "ratings"
                                value = {ratingValue}
                                //readOnly
                                onChange = {(event, newRating) => {
                                  setRatingValue(newRating);
                                }}

                           />  

Error on Screen:
image
Please see if I change the initial value in useState to 0 or blank,

When I click the rating icon it does show an output but not on screen.

No change in color nor any other
image

Thanks.

Your error message says that movie is not defined. It’s impossible to tell without seeing all the code, but it seems that you never defined this. If it is not declared/defined then that means that it would be undefined so movie.vote_average would though a null pointer exception and crash the app anyway.

I would figure that out first. JS is trying to tell you where it ran into a problem. Is that declared somewhere?

1 Like

Maybe it’s a prop? It would make some sense if the default value was a prop. If so check the props are being passed as expected.

1 Like

Hi @lasjorg and @kevinSmith

So the full code is here as below hope this might help me and you as well to get the thing correctly.

const Produts = () =>{

    const classes = useStyles();
    
    const [movieData, setMovieData] = useState([
        //the below is an fake api data which needs to be deleted when final disgn is ready and add real api from useEffect
        {
            "adult": false,
            "backdrop_path": "/7RyHsO4yDXtBv1zUU3mTpHeQ0d5.jpg",
            "genre_ids": [
            12,
            878,
            28
            ],
            "id": 299534,
            "original_language": "en",
            "original_title": "Avengers: Endgame",
            "overview": "After the devastating events of Avengers: Infinity War, the universe is in ruins due to the efforts of the Mad Titan, Thanos. With the help of remaining allies, the Avengers must assemble once more in order to undo Thanos' actions and restore order to the universe once and for all, no matter what consequences may be in store.",
            "popularity": 326.894,
            "poster_path": "/or06FN3Dka5tukK1e9sl16pB3iy.jpg",
            "release_date": "2019-04-24",
            "title": "Avengers: Endgame",
            "video": false,
            "vote_average": 8.3,
            "vote_count": 18957
            },
         
    ]);

//here I am trying to pass the vote_average value to useState as its initial value. 

    const [ratingValue, setRatingValue] = useState(movie.vote_average);

//finally am returning it using map function in rating component below
return (
        <> 
            <div className={classes.main}> 
            {movieData.map((movie) =>{
                 return(
                    <Card className={classes.cardMain} key={movie.id}>
                   <CardActionArea>
                       <CardMedia className = {classes.cardImage}>
                          <img style = {{width: '100%', height: '100%', objectFit: 'cover'}} 
                               src ={`https://image.tmdb.org/t/p/original${movie.poster_path}`} 
                               alt = "movie poster"/>
                       </CardMedia>
                       <CardContent className = {classes.cardContent}>
                           <Typography>  {movie.original_title} </Typography>
                           <Typography 
                                      className = {classes.typography1} 
                                      variant="body2" 
                                      component = "p"
                            > {movie.release_date} 
                            </Typography>
                           <Rating 
                                className = {classes.typography2} 
                                name = "ratings"
                                value = {ratingValue}
    //here am trying to render/return that vote_average value and then change when user clicks or selects
                                onChange = {(event, newRating) => {
                                  setRatingValue(newRating);
                                }}

                           />  
                       </CardContent>
                   </CardActionArea>
                   <CardActions >
                       <Button className = {classes.cardButton} >Watch</Button>
                       <Button className = {classes.cardButton}>Like</Button>
                       <Button className = {classes.cardButton}>Rent</Button>
                   </CardActions>
               </Card>
                 );
                   
            })}
           
            </div>
             
              
        </>
    )
};
export default Produts;
    

I hope am explaining it correctly. Please correct me if something is wrong here

Yeah, I think we see what you are trying to do. The problem is that JS has no idea what the movies variable is. Where is it declared? Is it supposed to come in on props, as lasjorg was suggesting?

Or, oh, looking at the code above, did you mean movieData[0]. vote_average. I’m not a big fan of initializing one state off another - I might put that default array in a constant. Also, if the ratingValue is always going to be that or be always and deterministically based on the movieData, you may not need a separate state for that, depending on what it will end up being.

1 Like

As said, you are not using the correct variable. But I don’t think it really makes sense to initialize the state to that anyway. The rating should always be coming from the currently iterated object in the array. It should also set the value on that object. Sure you can use the current value and set a new value to a separate temporary state variable, but it needs to get added back to the object it belongs to at the end.

1 Like

This topic was automatically closed 182 days after the last reply. New replies are no longer allowed.