https://kotlinlang.org logo
#compose
Title
# compose
j

Jorge Domínguez

09/16/2022, 9:37 PM
Is there any advantage in using remember for simply instatiating a class?
Copy code
val model = remember {
    Model(
        name = "John",
        lastName = "Doe",
        nationality = "Colombian",
        type = Type.DEVELOPER
    )
}
probably thinking about it too much but I'm not sure if re-instantiating the class on every recomposition has a significant cost
c

Chris Fillmore

09/16/2022, 9:46 PM
The way you’ve written this question makes it a bit hard to answer. For two reasons: 1. You don’t generally instantiate a model in your composable 2. Instantiating a model would accept arguments from somewhere, not hardcoded values as in your example I realize you’re just trying to illustrate an example, but it makes it hard to put your question in a meaningful real-world context, so it makes it hard to give a meaningful answer.
Are you just exploring and experimenting, or are you trying to solve a particular business problem?
j

Jorge Domínguez

09/16/2022, 10:15 PM
At work I'm using an internal library that has some predefined composables, these composables render data that you pass to them using these models, but you can think of them as state holders. What you're saying is correct, the actual arguments of the state holders are not hardcoded but instead are passed down to the parent composable, like this:
Copy code
@Composable
fun SomeComposable(
    uiState: UiState
) {
    val stateHolder = remember {
        StateHolder(
            title = uiState.title.format(),
            subtitle = uiState.subtitle,
            type = uiState.type
        )
    }
    
    ChildComposable(stateHolder = stateHolder)
}
This is as simple as it can get but in reality there are several state holders, all of which depend on the
uiState
, which comes from a ViewModel. that's also the reason why I'm not creating the state holders outside composition, because I need the reactivity of
viewModel.uiState.observeAsState()
You might think why I don't simply create the state holders inside the ViewModel and expose them in the
uiState
, the reason for that is that I need some string and drawable resources and don't wanna end up with a composable with lots of arguments
So to sum things up I wanna know if wrapping the StateHolder instantiation in
remember
has any benefits over simply having
Copy code
val stateHolder = StateHolder(
    ...
)
t

tad

09/17/2022, 12:04 AM
well,
stateHolder
would be recreated on every recomposition
along with all of its fields; e.g.
format()
would be called each time
Unless you're mutating state in
StateHolder
, I would just pass
title
,
subtitle
and
type
directly to
ChildComposable
. Right now, if any field in
uiState
changes, then this function is called and either
remember { StateHolder(...) }
or
StateHolder
is called, which has a nonzero cost. Personally, I don't think wrapping arguments in a type is worth it just to reduce the number of arguments to a composable function, and it can introduce subtle performance issues unless the wrapper type is itself
@Immutable
or inferred as such, or it's wired up to the composition with
@Stable
and
MutableState
fields. It's much simpler to avoid fighting the system and just pass your arguments directly, even if there are like 30 of them (in which case you might consider breaking up the function). So in short, it looks to me like the internal library isn't designed well for Compose, and I would raise that with your team.
160 Views