In that sense you are correct, most of the time it is a shallow copy. However, my problem is not the copy, or the amount of copies. My problem is the need to traverse the object graph to find and update an item.
The problem I am having. I got a UI state that is basically represented by two nested list, or rather a list of list. A list of menu sections where each section contains a list of menu items. Now anytime a user mark a menu item as favorite, the viewmodel gets an event to update with the menu item that needs to update.
Then comes the nightmare, traversing the 2 list to find and replace the menuItem with the updated favorite property, then trigger full screen recomposition again.
We improved find() performance a bit by using a map instead of a list. But still, updating the state is not so trivial. The map has to be copied to trigger recomposition.
On the other hand, updating the favorite property in the menuItem itself and just trigger recomposition sounds like a simple and efficient way, but people seem to go against such a move.