https://kotlinlang.org logo
#decompose
Title
# decompose
n

Nacho Ruiz Martin

12/03/2023, 7:36 AM
Hey! 👋 Following the principles shown in Artur Artikov’s posts, I am trying to decompose my screens into smaller components. To avoid duplicating logic, I am attempting to create components dynamically for each item of a list that is fetched from the network. The models inside are updated in response to several intents, such as user intents or push notifications so the component is observing the models that are stored in the local repository. Is this still the recommended approach for dynamic lists of components?
a

Arkadii Ivanov

12/03/2023, 10:36 AM
Absolutely not. Also you are looking at the old repo. Decompose now supports Child Pages navigation model, please give it a try. Alternatively, you can use Generic Navigation for custom navigation cases, by either using it directly or creating your own navigation API (e.g. extension on ComponentContext).
n

Nacho Ruiz Martin

12/03/2023, 5:20 PM
Sounds reasonable, the fact that it was in the old repo is what warned me about it being deprecated, actually. I thought the Child Pages navigation had the active page as mandatory. It's a normal list in my case, no active item.
a

Arkadii Ivanov

12/03/2023, 5:46 PM
You can just ignore the
index
property, and you can also use
pageStatus
lambda argument to control lifecycle states of the pages (e.g. make pages never destroyed).
Or you can implement your own navigation model (i.e. name it Child Items) and derive the implementation from Child Pages, but without
index
.
Here is an example of a custom navigation model where all items are always RESUMED.
n

Nacho Ruiz Martin

12/03/2023, 6:03 PM
Looks good, will try it tomorrow. Many thanks!!
👍 1
Hey, Arkadii! This works like a charm to display the initial list, but when the items are updated and I call to
setItems
again, the update is not behaving as expected. I guess this should be handled more carefully going through the list?
Or do you think it’s a better approach for each component to observe each item individually instead of the parent observing the whole list?
a

Arkadii Ivanov

12/04/2023, 9:03 AM
Could you elaborate what is exactly not expected?
n

Nacho Ruiz Martin

12/04/2023, 9:05 AM
Basically, items go back to the initial state. They do change and go back to their initial state. I’m unsure what happens behind scenes, but that’s what I’m experiencing.
Are they supposed to update smoothly just by calling
navigate
?
a

Arkadii Ivanov

12/04/2023, 9:10 AM
Yes, when you call navigate the items should be updated. But I didn't try the code myself.
n

Nacho Ruiz Martin

12/04/2023, 9:11 AM
Let me try to dig deeper and I’ll let you know.
a

Arkadii Ivanov

12/04/2023, 9:13 AM
The navigate function's lambda receives the current list of configurations and returns a new list that should be displayed.
n

Nacho Ruiz Martin

12/04/2023, 9:18 AM
Yep, saw that. Will it perform any magic in terms of comparing old and new list and check if configs are the same or something?
a

Arkadii Ivanov

12/04/2023, 9:18 AM
Yes, this is what it actually does.
👍 1
n

Nacho Ruiz Martin

12/04/2023, 9:19 AM
Let me check what it’s happening, in that case.
Nah, items are not going back to their initial state. What is happening is that when
navigate
is called to set a new list (with the same items, just in a different state), the internal mvikotlin’s store is getting recreated so the running coroutine gets cancelled (and on error, I’m resetting the items state to the previous one). Do you know if this is expected?
a

Arkadii Ivanov

12/04/2023, 10:34 AM
Each component instance in the list is represented by a unique configuration. If you change a configuration in the list, the related component is destroyed and another one with the new configuration is created.
You can treat a configuration as a unique identifier.
So it's not clear what you mean by "with the same items, just in a different state".
n

Nacho Ruiz Martin

12/04/2023, 10:38 AM
Each configuration is holding a view model (data class) that will be rendered in each component. Some properties of these models may and will change. I guess that since the new item is not
equal
with the old one, it’ll recreate the component/store. Should I override equals in some way or maybe just provide the id to this and make each subcomponent to observe changes independently?
a

Arkadii Ivanov

12/04/2023, 10:43 AM
Yeah, this is the reason. Arguments from a configuration are passed to the corresponding component via constructor. So when you have new arguments, it recreates component instances and supplies new arguments in them. You can remove all the changing data from configurations and only keep unique info (e.g. id). Then you can locate components in the list and call a method on them. Or your components may subscribe to updates in their constructors.
n

Nacho Ruiz Martin

12/04/2023, 10:44 AM
Yeah, sounds good, thank you! allo love
K 1