0

So I am attempting to create a movie voting app for my friends and I. I have most of it set up in react and I cant figure out how to set/update the state of the 'rating' object.

The array is set up as follows:

import React, { useState, createContext } from 'react';

export const MovieListContext = createContext();

export const MovieListProvider = (props) => {
    const [movieList, setMovieList] = useState([
        {
            name: "Test",
            rating: ""
        },
        {
            name: "Testing",
            rating: ""
        },
        {
            name: "Tester",
            rating: ""
        },
    ]);
    return (
        <MovieListContext.Provider value={[movieList, setMovieList]}>
            {props.children}
        </MovieListContext.Provider>
    )
}

Then I want to be able to write over the array and update the rating object with each one of our ratings

import React, { useState, useContext } from 'react';
import Movie from './Movie'
import {MovieListContext} from "../MovieListContext";
import VotingCandidates from "./VotingCandidates";

const VotingForm = () => {
    const [movieList, setMovieList] = useContext(MovieListContext);
    
    const handleRatingChange = (e, movieList) => {
        setMovieList([...movieList, {rating: e.target.value}]);
        console.log(movieList)
    }

    return (
        <div>
            {movieList.map(movieList => (
                <li key={movieList.name}>{movieList.name}
                <input onChange={handleRatingChange} type="text"/>
                </li>
                
            ))}

            
            <button>VOTE</button>
        </div>
    )
}

export default VotingForm

I can't figure out a way to make it so the state of the movieList.rating objects are able to be updated

Emile Bergeron
  • 17,074
  • 5
  • 83
  • 129
  • Does this answer your question? [Whats the best way to update an object in an array in ReactJS?](https://stackoverflow.com/questions/28121272/whats-the-best-way-to-update-an-object-in-an-array-in-reactjs) – Emile Bergeron Aug 20 '20 at 19:15

1 Answers1

0

In order to update a specific item in the array, you need to know which element you want to update. For that you will need something to differentiate. In your case you could use the name, but a unique id or the index of the item would be better. Then, you pass that to the even handler.

Personally I would do something like this:

  1. change the array to have id's
[
  { id: 1, name: "Test"},
  { id: 2, name: "Foo"}
]
  1. to map over the array in your jsx and pass the correct data to the event handler:
{movieList.map(item => (
  <li key={movieList.id}><input onChange={() => handleRatingChange(item, movieList)} /></li>
))}
  1. update the event handler to update the state
const handleRatingChange = (e, updatedItemId, movieList) => {
  setMovieList(movieList.map(item => {
    if(item.id == updatedItemId) {
      return {...item, rating: e.currentTarget.value}
    }
    return item
  }) 
}
Dharman
  • 30,962
  • 25
  • 85
  • 135
  • So I updated my code a bit and now I'm getting the following error: ```TypeError: Cannot read property 'map' of undefined``` – TeflonTrout Aug 20 '20 at 19:58
  • @TeflonTrout can you post your code? The error points out that whatever you are mapping is undefined or unknown at that point, so maybe what you passed into the function is wrong, or it is a typo? Hard to tell. Also, as an aside: why do you not just use the state inside the React component? – Jeroen Bourgois Aug 21 '20 at 05:38