1

I am trying to update a single object value (boolean) in my array using setState. Based on previous discussions, my approach does not mutate prior state, creates a copy of the original array, updates the copy, and then updates the original array. The 'issue' I have run into is that while the state updates my virtual list, the array does not re-render (FlatList in RN, specifically).

Previous Discussions Referenced: React: how to update state.item[1] in state using setState?

As a work around, I make a copy of my original array and then set the original array to empty. The cost is a very brief 'flicker' whenever the array re-renders.

Question: Is there a better way to update an object's value in my array AND trigger a re-render of the array elsewhere in my application?

Current Solution:

originalArray = [{ id: '123', randomKey: true }, {'234', randomKey: false }, ...]

const index = originalArray.findIndex(item => item.id === currentItemId)
if (index > -1) {
   const newArray = [...originalArray]
   setOriginalArray([]) // My solution to re-render the array
   let updatedItem = {...newArray[index]}
   updatedItem.randomKey = !randomKey // the value is a boolean
   newArray[index] = updatedItem
   setOriginalArray(newArray)
}

Cheers!

jasontulloch
  • 31
  • 1
  • 6
  • In what context is this code being run? It might help if you posted more code as I don't see why the `setOriginalArray([])` is necessary. Changes to the array, if stored in state, should re-render your component – gloo Jun 08 '22 at 17:36
  • The reason why changing my array state doesn't re-render my component is because I am making a shallow change by toggling the boolean between true and false (apologies I forgot the correct wording and couldn't find it). The length of my array does not change so it does not re-render on its own vs. if I were to add or remove an entire object to/from the array. I am using setOriginalArray([]) to change the length of my array to zero, which forces the originalArray to re-render when the new array is inserted. I think this can be improved because my cached images on my virtual list flicker. – jasontulloch Jun 08 '22 at 19:15
  • The length of the array does not matter if you are calling `setOriginalArray` with a `newArray`. The way React does [shallow comparison](https://stackoverflow.com/questions/36084515/how-does-shallow-compare-work-in-react) with arrays is checking whether their references are the same. React also [batches state updates outside of hooks](https://reactjs.org/docs/state-and-lifecycle.html#state-updates-may-be-asynchronous), which makes the flickering behavior your describe even stranger. That is why I am asking for more code to understand why your workaround is necessary. – gloo Jun 08 '22 at 19:40
  • I think my question was lacking clarity that I am talking about an array of objects, apologies. With that, my understanding is that shallow compare is looking at the keys in the objects, not the values of these keys. As discussed here? https://stackoverflow.com/questions/36084515/how-does-shallow-compare-work-in-react#:~:text=Shallow%20compare%20works%20by%20checking,the%20values%20inside%20that%20object. Also, I want to share my code but also am trying to figure out what is actually meaningful. originalArray is saved in state and the other page just renders it as a list, really nothing else. – jasontulloch Jun 08 '22 at 21:10

0 Answers0