Thread
#compose
    Colton Idle

    Colton Idle

    1 year ago
    Typing into a text field in a lazy column is laggy (even in the state codelab where it does this) Is that an issue or is there something we can do to fix this?
    a

    Alex Petitjean

    1 year ago
    If you're on Linux with multiple monitors, it could be related to this issue: https://github.com/JetBrains/compose-jb/issues/23 If not then I have no idea :blob-shrug:
    Colton Idle

    Colton Idle

    1 year ago
    Not desktop. Compose on android.
    Siyamed

    Siyamed

    1 year ago
    Responded on the ticket, not sure it was you who created the ticket @Colton Idle
    Colton Idle

    Colton Idle

    1 year ago
    Wasn't me but thanks! @Siyamed so the solution is to have an extra piece of state?
    Siyamed

    Siyamed

    1 year ago
    That is what it looks like
    Solution not in the sense of workaround but what it should be
    Colton Idle

    Colton Idle

    1 year ago
    Hm. That is odd to me because it goes against the whole single source of truth? But what do I know. I've been doing Compose for like 6 hours tops. Lol
    Siyamed

    Siyamed

    1 year ago
    you can one state for the whole app 😃 that would be single source of truth as well 😃
    I currently cant speak for the the specific code, but in general each of the TextFields should have their iwn state
    I believe there is something wrong with the codelab
    The recreation of the list was suspicious
    jim

    jim

    1 year ago
    Errr, I think @Colton Idle is right, unless I'm miss-reading this, comment #3 in the issue seems like a huge antipattern and is very much not the right solution.
    I agree with @Siyamed though that the
    todoItems.toMutableList().also {
    looks very suspicious and probably that codelab needs some additional review.
    Siyamed

    Siyamed

    1 year ago
    me reading the code as “each TextField has their own state” caused me to mislead. I strikethrough’ed it 🙂
    @jim having a listOf<MutableState> instead of mutableStateOf<List> is not an antipattern is it correct?
    jim

    jim

    1 year ago
    listOf<MutableState>
    is probably wrong, the user probably wanted
    mutableStateListOf
    instead.
    mutableStateOf<List>
    could be ok in some circumstances, but it has a very different behavior from
    mutableStateListOf
    Siyamed

    Siyamed

    1 year ago
    One question 😃
    MutableStateListOf is a mutable list right? So it would work well when we want to add and remove items
    Is it a good thing for a list of textfields that has their own independent state?
    I was wondering the drawbacks of - create an array of 10 for 10 person names - each array element is data for a textfield - create lazycolumn for those
    I would initially write this with an array of mutable states
    I was wondering if that is wrong
    jim

    jim

    1 year ago
    I'm not sure I understand the questions. If there are ten people and I want to use mutable objects, I'd probably have something like a
    mutableStateListOf<Person>
    with each person defined as:
    class Person {
       var name by mutableStateOf<String>()
    }
    If you could post a code snippet of the pattern you're imagining, maybe I can better comment on it. But as a general rule of thumb, probably mutableState should only be used as a property delegate backing a field or in a remember block. I'm not 100% confident enough to say that's a hard-and-fast rule yet (would love to see counterexamples) but that seems to be true off the top of my head without having thought too deeply about it.
    Siyamed

    Siyamed

    1 year ago
    The person example was good
    Thank you
    Colton Idle

    Colton Idle

    1 year ago
    So it seems like that codelab will need to be updated? @jim glad I was thinking correctly about the anti pattern in the comment of having multiple pieces of state. In your person example above... Is the person able to back a text field properly? So basically as long as I have mutableStateListOf<Person> in my ViewModel and class Person { var name by mutableStateOf<String>() } Then I would just pass person.name to the text field? And everything should work right? Sorry on mobile or else I'd try but I'm really curious in making sure I understand this correctly. I have a use case of building a dynamic form (think a Google form) and so I want to use a LazyColumn (for best perf) and so I want to make sure I only have a single piece of state.
    jim

    jim

    1 year ago
    LazyColumn(...) { index, person ->
        TextField(value=person.value, onChange={person.name = it})
    }
    Colton Idle

    Colton Idle

    1 year ago
    @jim was able to get to a desktop and verify that edit texts in a lazy work fine. Thanks @jim no duplication of state either!
    class MainActivity : AppCompatActivity() {
        override fun onCreate(savedInstanceState: Bundle?) {
            super.onCreate(savedInstanceState)
    
            val listOfPeeps = mutableStateListOf<Person>()
    
            listOfPeeps.add(Person())
            listOfPeeps.add(Person())
            listOfPeeps.add(Person())
    
            setContent {
                ComposeTextFieldTheme {
                    Surface(color = MaterialTheme.colors.background) {
                        LazyColumn(content = {
                            item {
                                Button(onClick = { listOfPeeps.add(Person()) }) {
                                    Text(text = "Add person to list")
                                }
                            }
                            items(listOfPeeps) { person: Person ->
                                TextField(value = person.name, onValueChange = { person.name = it })
                            }
                        })
                    }
                }
            }
        }
    }
    
    class Person {
        var name by mutableStateOf<String>("")
    }
    If you're still watching this thread, one thing I'm still not 100% sure about is why I need
    var name by mutableStateOf<String>("")
    Couldn't I just have a var name = "" since the list is
    mutableStateListOf
    ?
    jim

    jim

    1 year ago
    The
    mutableStateList
    only notifies observers when the LIST changes, not when an item within the list is mutated. If you want to be notified when the item within the list changes, that item must be observable (via state).
    Colton Idle

    Colton Idle

    1 year ago
    gotcha. makes sense. still learning, but yeah. this was pretty simple in the end to get working as intended.
    unfortunately the codelab threw me off.
    jim

    jim

    1 year ago
    If the codelab threw you off, please file a bug with the section that threw you off and suggested updates to make it less misleading.
    Colton Idle

    Colton Idle

    1 year ago
    @Siyamed linked to someone else that also had codelab trouble. I'll star it though. 😁
    @jim "The 
    mutableStateList
     only notifies observers when the LIST changes, not when an item within the list is mutated.  If you want to be notified when the item within the list changes, that item must be observable (via state)." So something that is messing with me here is that I've been really hammering home the point that everything should be immutable if it can be. Especially in a kotlin data class like Person. Doing mutableStateOf<String> "feels" wrong. Is my person still following the "rule" of favoring immutablilty when possible?
    jim

    jim

    1 year ago
    You could make your person be a:
    data class Person(val name: String)
    And just re-create the person if the name changes. That would be immutable.
    You could also have a
    mutableStateListOf<String>()
    , as String is immutable so you don't need to wrap it in a
    mutableStateOf
    and can just remove and add strings as needed (although that gives you less room to grow in the future).
    But no, if you are using any sort of
    mutableState
    then you are not favoring immutability.
    Colton Idle

    Colton Idle

    1 year ago
    Interesting. Still learning and I'm not sure this makes 100% sense yet, but I think it's clicking. Really the thing I'm trying to wrap my head around is if I needed a list of 10000 TextFields, how I would model that. Arguing with myself if
    data class Person(val name: String)
    is better, or
    class Person {
       var name by mutableStateOf<String>()
    }
    jim

    jim

    1 year ago
    Which one is better probably depends more on the rest of your app and data model, than a hard and fast rule. But the rule of thumb is to favor immutability, so maybe I'd go with the first one? Or maybe it's a coin toss.
    Colton Idle

    Colton Idle

    1 year ago
    @jim aha. Okay. I didn't know the first option was still "okay". I thought I "had" to use the second option in order for a list of TextFields to work. I will have to try this in a sample that isn't the Compose State codelab. I updated the codelab to use the mutableStateListOf and I was still seeing laggy typing, and so I thought the codelab was completely wrong since it didn't use
    var name by mutableStateOf<String>()