1

I'm working (learning) in React. I have an array of objects which hold info on gamertags. They are rated with up to five stars and this function is called when a user clicks on the stars in the GUI to alter the rating.

my solution: I make a copy of state, iterate over the copy, check each entry for the key, reassign the number of stars, then use my setState hook to assign the altered array.

Is there a more concise way to do this? I searched all over stack and google and couldn't find anything. I feel like I should be able to map, use an arrow function and or a ternary. Thanks for any comments on styles, JS and ES6 seems to be all about that. Thx fam.

  function changeStars(stars, key) {
    console.log(stars, key);
    const newRatingInventory = [ ...tagInventory];

    for (const [index] of newRatingInventory.entries()) {
      if (newRatingInventory[index].timeStamp === key) {
        newRatingInventory[index].stars = stars;
      }
    }
    setTagInventory([...newRatingInventory]);

2 Answers 2

1

Using the spread syntax doesn't creates a deep copy - it just creates a new array but the objects are not cloned. So any changes made to any object inside the new array will mutate the original object.

Currently you are mutating the state directly which is not the correct way to update the state in React.

You should use the .map() method to iterate over the array, create and return a new object if the condition newRatingInventory[index].timeStamp === key evaluates to true.

function changeStars(stars, key) {
    const newState = tagInventory.map(obj => {
       if (obj.timeStamp === key) { 
          // return a new object with the updated 
          // value of "stars" property.
          return { ...obj, stars };
       }
       
       // if the above condition is not true,
       // return the current object as it is.
       return obj;
    });
   
    // update the state
    setTagInventory(newState);
}
Sign up to request clarification or add additional context in comments.

1 Comment

works like a champ. thx, i didn't realize it wasn't a deep copy, i googled it and learned that the spread operator only goes 1 level deep on an array, so like you said, the objects themselves are shallow and not clones. glad i asked, this is super helpful to know. thx, i appreciate you
0

There is a multipal way to do this

my recommendation one is map.

const changeStars = (stars, key) => {
let tempRating = tagInventory && tagInventory.length > 0 && 
    tagInventory.map(item => item.timeStamp === key ? {...item, stars} : item);
 setTagInventory(tempRating)
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.