Besides using a view model, how can I set a State ...
# compose
t
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
Copy code
@Composable
fun Parent() {
    var state by remember { mutableStateof(false) }
    Child(onSomeEvent = { state = true })
}

@Composable
fun Child(onSomeEvent: () -> Unit) {
    Button(onClick = onSomeEvent)
}
☝️ 4
t
Wow - so you have to define the function in the parent and pass the event. Otherwise, a viewModel is the alternative?
z
Using callbacks to avoid data dependencies between components like that is the recommended best practice.
j
@Tony Mykhaylovsky I think it is better if you pass the actions to the childs and you keep the ViewModel at the parent
p
a viewModel is a less preferable alternative
z
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.
a
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
p
I think they're just trying to type less Adam 😁
a
always 😛
I'm foreshadowing some of the work going into `TextField`s at the moment
t
Very helpful - thank you all
So if I have a busy Child View, it could potentially have 5 parameter functions?
j
you could make your view composable as well
p
you can group them in something called
actions
🔝 1
t
Both parent and child are composable
j
Copy code
@Composable
fun parent() {
    childContainer(...paremeters) {
         SomeOtherComposable()
    }
}

@Composable
fun childContainer(...paremeters, children: @Composable () -> Unit) {
     SpecialStuff()
     children()
}
t
Overwhelming amount of help - thank you 🙂
j
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
z
To group them, like Adam suggested:
Copy code
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() })
}
☝️ 1
t
That's great - thank you