Thread
#compose
    Tony Mykhaylovsky

    Tony Mykhaylovsky

    1 year ago
    Besides using a view model, how can I set a State variable from a child View?
    I have a boolean defined as isMap and it's set to false by default. I would like to be able to change that to true from a child view. In SwiftUI, this can be accomplished by creating a binding object on the child view. Not sure how to do it in Jetpack Compose. THANK YOU!
    s

    Se7eN

    1 year ago
    @Composable
    fun Parent() {
        var state by remember { mutableStateof(false) }
        Child(onSomeEvent = { state = true })
    }
    
    @Composable
    fun Child(onSomeEvent: () -> Unit) {
        Button(onClick = onSomeEvent)
    }
    Tony Mykhaylovsky

    Tony Mykhaylovsky

    1 year ago
    Wow - so you have to define the function in the parent and pass the event. Otherwise, a viewModel is the alternative?
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    Using callbacks to avoid data dependencies between components like that is the recommended best practice.
    Javier

    Javier

    1 year ago
    @Tony Mykhaylovsky I think it is better if you pass the actions to the childs and you keep the ViewModel at the parent
    ppvi

    ppvi

    1 year ago
    a viewModel is a less preferable alternative
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    You could also do something like pass a
    MutableState
    down to your child and have the child mutate the state itself, but that increases coupling and is considered more of a bad practice.
    Adam Powell

    Adam Powell

    1 year ago
    if you find you need that kind of guaranteed-synchronous behavior it's often better to define an object or interface you pass to the composable
    passing
    MutableState<MyData>
    around is kind of like passing around
    Pair<Foo, Bar>
    instead of defining a data class for the abstraction you're trying to represent with it
    ppvi

    ppvi

    1 year ago
    I think they're just trying to type less Adam 😁
    Adam Powell

    Adam Powell

    1 year ago
    always 😛
    I'm foreshadowing some of the work going into TextFields at the moment
    Tony Mykhaylovsky

    Tony Mykhaylovsky

    1 year ago
    Very helpful - thank you all
    So if I have a busy Child View, it could potentially have 5 parameter functions?
    j

    Joost Klitsie

    1 year ago
    you could make your view composable as well
    ppvi

    ppvi

    1 year ago
    you can group them in something called
    actions
    Tony Mykhaylovsky

    Tony Mykhaylovsky

    1 year ago
    Both parent and child are composable
    j

    Joost Klitsie

    1 year ago
    @Composable
    fun parent() {
        childContainer(...paremeters) {
             SomeOtherComposable()
        }
    }
    
    @Composable
    fun childContainer(...paremeters, children: @Composable () -> Unit) {
         SpecialStuff()
         children()
    }
    Tony Mykhaylovsky

    Tony Mykhaylovsky

    1 year ago
    Overwhelming amount of help - thank you 🙂
    j

    Joost Klitsie

    1 year ago
    I mean if you want to adjust behavior of the child in many ways, you might just want to extract some basic behavior in a child and simply pass on more children to the child, I think this was explained in some interesting video
    lemme check it

    https://www.youtube.com/watch?v=SMOhl9RK0BA

    here we go, around 8:50
    Zach Klippenstein (he/him) [MOD]

    Zach Klippenstein (he/him) [MOD]

    1 year ago
    To group them, like Adam suggested:
    class YourComplicatedState {
      private val _foo: MutableState<Foo> = mutableStateOf(…)
      private val _bar: MutableState<Bar> = mutableStateOf(…)
      val foo: State<Foo> = _foo
      val bar: State<Bar> = _bar
    
      fun doSomeAction() {
        _foo.value = …
        _bar.value = …
      }
    }
    
    @Composable
    fun Parent() {
        var state by remember { YourComplicatedState() }
        Child(state)
    }
    
    @Composable
    fun Child(state: YourComplicatedState) {
        Button(onClick = { state.doSomeAction() })
    }
    Tony Mykhaylovsky

    Tony Mykhaylovsky

    1 year ago
    That's great - thank you