In the chapter on Designing the State Shape, the docs suggest to keep your state in an object keyed by ID:
Keep every entity in an object stored with
Think of the app’s state as a database.
That's the key idea.
1) Having objects with unique IDs allows you to always use that id when referencing the object, so you have to pass the minimum amount of data between actions and reducers. It is more efficient than using array.find(...). If you use the array approach you have to pass the entire object and that can get messy very soon, you might end up recreating the object on different reducers, actions, or even in the container (you dont want that). Views will always be able to get the full object even if their associated reducer only contains the ID, because when mapping the state you'll get the collection somewhere (the view gets the whole state to map it to the properties). Because of all of what i've said, actions end up having the minimal amount of parameters, and reducers the minimal amount of information, give it a try, try both methods and you'll see the architecture ends up more scalable and clean using IDs if collections do have ID.
2) The connection to the API should not affect the architecture of your storage and reducers, that's why you have actions, to keep the separation of concerns. Just put your conversion logic in and out of the API in a reusable module, import that module in the actions that use the API, and that should be it.
3) I used arrays for structures with IDs, and these are the unforeseen consequences i've suffered:
I ended up changing my data structure and rewriting a lot of code. You have been warned, please don't get yourself in trouble.
Also:
4) Most collections with IDs are meant to use the ID as a reference to the whole object, you should take advantage of that. The API calls will get the ID and then the rest of the parameters, so will your actions and reducers.