Is it better to store individual class properties ...
# compose
v
Is it better to store individual class properties as MutableState or the whole class? (Example of what I mean in 🧵)
Copy code
/* Screen 1 */
data class ScreenState(
    val firstName: String,
    val lastName: String,
)

@Composable fun Screen() {
    val screenState = remember { mutableStateOf(ScreenState("Hello", "World")) }
    SomeComponent(
        firstName = screenState.value.firstName,
        lastName = screenState.value.lastName,
        setFirstName = { screenState.value = screenState.value.copy(firstName = it) }
    )
}

/* Screen 2 */
class ScreenState2() {
    private val _firstName = mutableStateOf("Hello")
    val firstName: State<String> get() = _firstName
    fun setFirstName(name: String) { _firstName.value = name }
    
    private val _lastName = mutableStateOf("World")
    val lastName: State<String> get() = _lastName
}

@Composable fun Screen2(screenState: ScreenState2) {
    SomeComponent(
        firstName = screenState.firstName.value,
        lastName = screenState.lastName.value,
        setFirstName = screenState::setFirstName,
    )
}

@Composable fun SomeComponent(firstName: String, lastName: String, setFirstName: (String) -> Unit) {
    TODO()
}
What is the practical difference here? Any performance benefits?
I'd prefer the second approach since especially with complex state I'd imagine updating some deeply nested state would become quite troublesome with the first approach, but is my intuition wrong here?
👀 1
s
You could also do:
Copy code
class ScreenState(
    firstNameState: MutableState<String>,
    lastNameState: MutableState<String>,
) {
    var firstName by firstNameState
    var lastName by lastNameState
}

@Composable
fun rememberScreenState() {
    val firstNameState = rememeber { mutableStateOf("") }
    val lastNameState = rememeber { mutableStateOf("") }

    return remember {
        ScreenState(firstNameState, lastNameState)
    }
}
z
I think the latter approach is slightly better, at least it should result in fewer recompositions if only one of the fields change
m
No, i don’t think that is true
2
c
I’m strongly of the opinion that using a data class is much better than individual
States
for each property. The high-level reasoning is that it is difficult to combine those individual properties if you need to use both values at once, but combining properties is trivial when the state is just an immutable data class. I’ve got a much more in-depth discussion on how to model state in the documentation for my MVI library, ballast
👍 2
👍🏽 1
m
exactly
a
Much easier to reason about changes with a single data class for state
Otherwise you can end up with many individual fields to manage
👆 1
c
For me, I typically just have each screen state with a bunch of mutableStateOf. Seems to work fine /shruggie
a
Idk if I recommend that either. Why need that when compose does smart diffing anyways?
m
for me, one screen one data class
c
Def seems to be stylistic differences, but curious what the compose team says here. I am but a simple noob at this stuff.
❤️ 1
a
I think there are already many discussions on this. For example this thread.
❤️ 1
a
Also the memory overhead of state for each smal string or variable. And initialization overhead of registering each one. Keep state small in places it's used and break the data class into smaller reusable pieces
v
Thanks everyone for the answers 😄