React: Updating multiple object variables in array

Viewed 119

I want to implement a voting system in my app where you can vote thumbs-up or thumbs-down for a selected movie. The ratings will be saved in a ratings array of objects that contain movie title, id, thumbs-up votes and thumbs-down votes. If a movie has no votes, the first vote will add the new object into the ratings array, and subsequent votes will update the thumbs-up votes and thumbs-down votes of the object. My current code works for the first thumbs-up vote and adds the new obj into the array, but does not update the vote count for subsequent votes. How can I update the votes in the movie object for both thumbs-up and thumbs-down votes? This involves incrementing the count depending on whether the thumbs-up or thumbs-down button is clicked. How can I handle this besides creating separate but similar functions for each button like I’ve already started to do? Any help is greatly appreciated, thank you in advance!

const ThumbRating = ( {id, title} ) => {

const [thumbsUpCount, setthumbsUpCount] = useState(0);
const [thumbsDownCount, setthumbsDownCount] = useState(0);
const [ratings, setRatings] = useState([]);

const newUpVote = (id) => {
    if (thumbsUpCount === 0 && thumbsDownCount === 0) {
        setthumbsUpCount(thumbsUpCount + 1);
        const obj = {
            id: {id},
            title: {title},
            thumbsUpCount: thumbsUpCount +1,
            thumbsDownCount: thumbsDownCount
        }
        setRatings([obj])
    } else {
        setthumbsUpCount(thumbsUpCount +1)
        handleThumbsUp(id, thumbsUpCount +1)
    } 
}

const handleThumbsUp = (id, thumbsUpCount) => {
    setRatings(ratings.map(obj => {
        if (obj.id !== id) return obj
        return {...obj, thumbsUpCount: thumbsUpCount +1}
    }))
  }

return (
<div className="thumb-rating">
    <p>Would you recommend this movie?</p>
<table>
<tbody>
    <tr>
        <td>
        <div >
        <button className="thumbs-up" onClick={() => newUpVote(id)}>
            <i className="fa fa-thumbs-up fa-4x" />
        </button>
        </div>
        </td>
        <td>
        <div >
        <button className="thumbs-down" onClick={() => setthumbsDownCount(thumbsDownCount + 1)}>
            <i className="fa fa-thumbs-down fa-4x" />
        </button>
        </div>
        </td>
    </tr>
    <tr>
        <td>
            <h2>Yes: {thumbsUpCount} </h2>
        </td>
        <td>
            <h2>No: {thumbsDownCount} </h2>
        </td>
    </tr>
</tbody>
</table>
</div>
)
}
1 Answers

There is My solution:

The handlerHandleCountDown is working and the state is correcting updating.

Now you can try to handle the countDown based on the example.

Do not forget to pass id and title as props to your component.

import { useState } from 'react'

const ThumbRating = ({ id, title }) => {
  const [thumbsUpCount, setthumbsUpCount] = useState(0)
  const [thumbsDownCount, setthumbsDownCount] = useState(0)
  const [ratings, setRatings] = useState([])

  const newUpVote = (id) => {
    if (thumbsUpCount === 0 && thumbsDownCount === 0) {
      setthumbsUpCount(thumbsUpCount + 1)
      const obj = {
        id, // id:id also works but id: {id} will not
        title,
        thumbsUpCount: thumbsUpCount + 1,
        thumbsDownCount: thumbsDownCount,
      }
      setRatings([obj])
    } else {
      setthumbsUpCount(thumbsUpCount + 1)
      handleThumbsUp(id)
    }
  }

  const handleThumbsUp = (id) => {
    // Is better to use the find method when you want to find a single element in an array

    const objectToBeUpdated = ratings.find((obj) => obj.id === id)

    objectToBeUpdated.thumbsUpCount += 1 // I assumed you will always update by one
    setRatings([objectToBeUpdated])
  }

  return (
    <div className='thumb-rating'>
      <p>Would you recommend this movie?</p>
      <table>
        <tbody>
          <tr>
            <td>
              <div>
                <button className='thumbs-up' onClick={() => newUpVote(id)}>
                  <i className='fa fa-thumbs-up fa-4x' />
                </button>
              </div>
            </td>
            <td>
              <div>
                <button
                  className='thumbs-down'
                  onClick={() => setthumbsDownCount(thumbsDownCount + 1)}
                >
                  <i className='fa fa-thumbs-down fa-4x' />
                </button>
              </div>
            </td>
          </tr>
          <tr>
            <td>
              <h2>Yes: {thumbsUpCount} </h2>
            </td>
            <td>
              <h2>No: {thumbsDownCount} </h2>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  )
}

export default ThumbRating
Related